「C++系列」数据结构

news2024/9/21 11:01:50

文章目录

  • 一、数据结构
    • 1. 线性数据结构
    • 2. 非线性数据结构
    • 3. 其他重要数据结构
  • 二、定义数据结构
    • 1. 数组(Array)
    • 2. 链表(LinkedList)
    • 3. 栈(Stack)
  • 三、指针、关键字
    • 1. 指针
      • 链表
    • 2. 关键字
  • 四、相关链接

一、数据结构

C++作为一种高效的编程语言,提供了丰富的内置数据类型和库,支持各种复杂的数据结构实现。C++中的数据结构主要分为线性数据结构和非线性数据结构两大类,每种数据结构都有其独特的特点和应用场景。

1. 线性数据结构

线性数据结构中的数据元素之间存在一对一的线性关系。常见的C++线性数据结构包括:

  1. 数组(Array)
  • 定义:数组是一种聚合数据类型,用于存储相同类型的元素集合。
  • 特点:通过索引访问元素,访问速度快(O(1)),但插入和删除操作(尤其是中间位置)可能较慢。数组分为静态数组和动态数组,静态数组在编译时确定大小,不能动态调整;动态数组在运行时分配内存,可以动态调整大小(如使用newdelete操作符,或在C++11及以后版本中使用std::vector)。
  1. 链表(Linked List)
  • 定义:链表是一种动态数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针。
  • 特点:插入和删除操作(尤其是中间位置)速度快(O(1)),但访问元素可能较慢(需要遍历链表)。链表分为单向链表、双向链表和循环链表等。
  1. 栈(Stack)
  • 定义:栈是一种后进先出(LIFO)的数据结构。
  • 特点:主要操作包括push(压栈,添加元素到栈顶)、pop(弹栈,移除栈顶元素)和peek(查看栈顶元素)。栈可以使用数组或链表来实现,C++标准模板库(STL)提供了std::stack容器。
  1. 队列(Queue)
  • 定义:队列是一种先进先出(FIFO)的数据结构。
  • 特点:主要操作包括enqueue(入队,添加元素到队尾)、dequeue(出队,移除队头元素)和front/back(查看队头/队尾元素)。队列也可以使用数组或链表来实现,C++ STL提供了std::queue容器。

2. 非线性数据结构

非线性数据结构中的数据元素之间存在一对多或多对多的关系。常见的C++非线性数据结构包括:

  1. 树(Tree)
  • 定义:树是一种层次化的数据结构,由节点组成,每个节点有零个或多个子节点。
  • 特点:节点之间的关系是层次和分支的,如二叉树、平衡二叉树、红黑树等。树结构常用于实现排序、搜索和存储层次数据。
  1. 图(Graph)
  • 定义:图由节点(或顶点)和边组成,用于表示复杂的关系网络。
  • 特点:节点之间的关系是多对多的,常用于表示社交网络、地图等。图分为无向图和有向图,图的表示方法有邻接矩阵和邻接表等。
  1. 哈希表(Hash Table)
  • 定义:哈希表是一种通过哈希函数将键映射到存储位置的数据结构。
  • 特点:访问速度快(平均时间复杂度为O(1)),常用于实现快速查找、插入和删除操作。
  1. 堆(Heap)
  • 定义:堆是一种特殊的树形数据结构,满足堆属性(父节点的值大于或等于(最大堆)或小于或等于(最小堆)其子节点的值)。
  • 特点:常用于实现优先队列,如操作系统的任务调度等。C++ STL提供了std::priority_queue容器,它底层通常使用最大堆实现。

3. 其他重要数据结构

  • 字符串(String):虽然字符串通常不被视为一种独立的数据结构,但在C++中,字符串是一个非常重要的数据类型,常用于表示文本数据。C++标准库提供了std::string类来管理字符串。

二、定义数据结构

在C++中,数据结构是通过类(class)或结构体(struct)来定义的,这些结构包含了数据成员(即属性)和成员函数(即方法),用于操作这些数据。下面我将给出几种常见数据结构的定义及简单案例。

1. 数组(Array)

虽然数组不是通过类或结构体显式定义的,但它是C++中最基本的数据结构之一。不过,为了展示自定义数据结构的思路,我们可以考虑一个封装了动态数组的类(类似于std::vector的简化版)。

#include <iostream>

class DynamicArray {
private:
    int* arr;
    int capacity;
    int size;

public:
    DynamicArray(int capacity = 10) : capacity(capacity), size(0), arr(new int[capacity]) {}

    ~DynamicArray() {
        delete[] arr;
    }

    void add(int element) {
        if (size == capacity) {
            // 简化处理,实际应更复杂地处理扩容
            capacity *= 2;
            int* newArr = new int[capacity];
            for (int i = 0; i < size; ++i) {
                newArr[i] = arr[i];
            }
            delete[] arr;
            arr = newArr;
        }
        arr[size++] = element;
    }

    void print() {
        for (int i = 0; i < size; ++i) {
            std::cout << arr[i] << " ";
        }
        std::cout << std::endl;
    }
};

int main() {
    DynamicArray myArray;
    myArray.add(1);
    myArray.add(2);
    myArray.add(3);
    myArray.print(); // 输出: 1 2 3
    return 0;
}

2. 链表(LinkedList)

链表是一种动态数据结构,节点包含数据和指向下一个节点的指针。

#include <iostream>

struct ListNode {
    int val;
    ListNode* next;
    ListNode(int x) : val(x), next(nullptr) {}
};

class LinkedList {
private:
    ListNode* head;

public:
    LinkedList() : head(nullptr) {}

    void append(int val) {
        ListNode* newNode = new ListNode(val);
        if (!head) {
            head = newNode;
        } else {
            ListNode* current = head;
            while (current->next) {
                current = current->next;
            }
            current->next = newNode;
        }
    }

    void print() {
        ListNode* current = head;
        while (current) {
            std::cout << current->val << " ";
            current = current->next;
        }
        std::cout << std::endl;
    }

    ~LinkedList() {
        // 简化处理,实际应递归删除所有节点
        while (head) {
            ListNode* temp = head;
            head = head->next;
            delete temp;
        }
    }
};

int main() {
    LinkedList myList;
    myList.append(1);
    myList.append(2);
    myList.append(3);
    myList.print(); // 输出: 1 2 3
    return 0;
}

3. 栈(Stack)

栈是一种后进先出(LIFO)的数据结构,可以使用数组或链表实现。

#include <iostream>
#include <vector>

class Stack {
private:
    std::vector<int> elements;

public:
    void push(int val) {
        elements.push_back(val);
    }

    int pop() {
        if (elements.empty()) {
            throw std::out_of_range("Stack is empty!");
        }
        int top = elements.back();
        elements.pop_back();
        return top;
    }

    int top() {
        if (elements.empty()) {
            throw std::out_of_range("Stack is empty!");
        }
        return elements.back();
    }

    bool empty() {
        return elements.empty();
    }
};

int main() {
    Stack myStack;
    myStack.push(1);
}

三、指针、关键字

在C++中,数据结构和指针、关键字是紧密相关的概念。指针是C++中一个非常强大的特性,它允许程序直接访问和操作内存地址。而关键字则是C++语言预留的、具有特殊含义的单词,它们不能被用作变量名、函数名等标识符。下面我将分别解释指针在数据结构中的应用,以及几个与数据结构紧密相关的C++关键字。

1. 指针

指针在数据结构中扮演着至关重要的角色。它们允许我们动态地创建和操作数据结构,如链表、树和图等。通过使用指针,我们可以构建出复杂的数据结构,这些结构能够高效地存储和访问数据。

链表

在链表中,每个节点都包含数据和指向下一个节点的指针。这些指针允许我们遍历链表,并在需要时插入或删除节点。

struct ListNode {
    int val;
    ListNode* next;
    ListNode(int x) : val(x), next(nullptr) {}
};

在树中,每个节点通常包含数据和指向其子节点的指针。这些指针允许我们访问树中的任意节点,并执行诸如搜索、插入和删除等操作。

struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

2. 关键字

  1. classstruct

classstruct 关键字用于定义类。在C++中,类和结构体非常相似,但默认情况下,类的成员是私有的(private),而结构体的成员是公共的(public)。然而,这种差异可以通过显式指定成员访问修饰符来覆盖。类和结构体都可用于定义复杂的数据结构。

  1. newdelete

newdelete 关键字用于在堆上动态地分配和释放内存。这对于创建需要动态大小的数据结构(如动态数组、链表等)非常有用。

  1. privateprotectedpublic

这些关键字用于指定类成员的访问级别。在定义类时,它们决定了哪些成员可以从类的外部访问。这对于封装和隐藏数据结构的内部实现细节非常重要。

  1. static

static 关键字在类中有多种用途,包括声明静态成员变量和静态成员函数。静态成员变量在类的所有对象之间共享,而静态成员函数则不能直接访问类的非静态成员。

  1. template

template 关键字用于定义模板类、模板函数等。模板是C++泛型编程的基础,允许我们编写与类型无关的代码。这对于创建可重用且类型安全的数据结构非常有用。

  1. typename

typename 关键字用于在模板定义中指示紧随其后的标识符是一个类型。这在模板编程中尤其有用,因为它可以帮助编译器区分类型名和变量名。
在这里插入图片描述

四、相关链接

  1. Visual Studio Code下载地址
  2. Sublime Text下载地址
  3. 「C++系列」C++简介、应用领域
  4. 「C++系列」C++ 基本语法
  5. 「C++系列」C++ 数据类型
  6. 「C++系列」C++ 变量类型
  7. 「C++系列」C++ 变量作用域
  8. 「C++系列」C++ 常量知识点-细致讲解
  9. 「C++系列」C++ 修饰符类型
  10. 「C++系列」一篇文章说透【存储类】
  11. 「C++系列」一篇文章讲透【运算符】
  12. 「C++系列」循环
  13. 「C++系列」判断
  14. 「C++系列」函数/内置函数
  15. 「C++系列」数字/随机数
  16. 「C++系列」数组
  17. 「C++系列」字符串
  18. 「C++系列」指针
  19. 「C++系列」引用
  20. 「C++系列」日期/时间
  21. 「C++系列」输入/输出

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2051765.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【TCP/IP】UDP协议数据格式和报文格式

学习一个网络协议&#xff0c;主要就是学习“数据格式”/“报文格式” 源端口/目的端口 端口号是属于传输层的概念UDP 报头使用两个自己的长度来表示端口号之所以端口号的范围是 0~65535&#xff0c;是因为底层网络协议做出了强制要求如果使用一个 10 w 这样的端口&#xff0…

机器学习:多元线性回归模型

目录 前言 一、讲在前面 1.多元_血压.csv&#xff1a; 2.完整代码&#xff1a; 3.运行结果&#xff1a; 二、实现步骤 1.导入库 2.导入数据 3.绘制散点图&#xff08;这步可以省略&#xff09; ​编辑 4.求特征和标签的相关系数 5.建立并训练线性回归模型 6.检验模…

NtripShare全站仪自动化监测之气象改正

最近有幸和自动化监测领域权威专家进行交流&#xff0c;讨论到全站仪气象改正的问题&#xff0c;因为有些观点与专家不太一致&#xff0c;所以再次温习了一下全站仪气象改正的技术细节。 气象改正的概念 全站仪一般利用光波进行测距&#xff0c;首先仪器会处理测距光波的相位漂…

C++| QT图片调整透明度叠加

QT图片调整透明度叠加 实际效果界面UI放置控件设置布局界面自适应 代码项目工程的文件初始化按钮功能滑动条功能图片调整透明度叠加 实际效果 三个图片&#xff08;QLabel&#xff09;显示&#xff0c;两个按钮&#xff08;QPushButton&#xff09;加载图片&#xff0c;一个&a…

【Java学习】反射和枚举详解

所属专栏&#xff1a;Java学习 &#x1f341;1. 反射 在程序运行时&#xff0c;可以动态地创建对象、调用方法、访问和修改字段&#xff0c;以及获取类的各种属性信息&#xff08;如成员变量、方法、构造函数等&#xff09;&#xff0c;这种机制就称为反射 反射相关的类 类名用…

【算法】马踏棋盘(骑士周游)问题回溯算法实现以及使用贪心算法优化

目录 1.游戏规则 2.算法分析 3.解决步骤和思路 4.马踏棋盘算法的代码实现 4.1计算马儿还能走哪些位置 4.2马踏棋盘的核心代码 4.3马踏棋盘算法完整代码 4.4使用贪心算法进行优化 4.4.1思路 4.4.2代码实现 1.游戏规则 将马儿随机放在国际象棋的 8*8 棋盘的某个方格中…

阶段练习——minishell

目录 &#xff08;一&#xff09;文件复制&#xff08;my_cp函数&#xff09; &#xff08;二&#xff09;文件内容查看&#xff08;my_cat函数&#xff09; &#xff08;三&#xff09;切换目录&#xff08;my_cd函数&#xff09; &#xff08;四&#xff09;列出目录内容…

一款专为IntelliJ IDEA用户设计的插件,极大简化Spring项目中的API调试过程,功能强大(附源码)

前言 在软件开发过程中&#xff0c;尤其是Spring MVC(Boot)项目中&#xff0c;API调试调用是一项常见但繁琐的任务。现有的开发工具虽然提供了一些支持&#xff0c;但往往存在效率不高、操作复杂等问题。为了处理这些痛点&#xff0c;提升开发效率&#xff0c;一款新的工具应运…

python 捕获异常

捕获指定异常 e 是保存的异常信息 捕获多个异常

快速体验fastllm安装部署并支持AMD ROCm推理加速

序言 fastllm是纯c实现&#xff0c;无第三方依赖的高性能大模型推理库。 本文以国产海光DCU为例&#xff0c;在AMD ROCm平台下编译部署fastllm以实现LLMs模型推理加速。 测试平台&#xff1a;曙光超算互联网平台SCNet GPU/DCU&#xff1a;异构加速卡AI 显存64GB PCIE&#…

Selenium + Python 自动化测试18(数据驱动实现测试)

我们的目标是&#xff1a;按照这一套资料学习下来&#xff0c;大家可以独立完成自动化测试的任务。 上一篇我们讨论了数据驱动测试中如何读取Excel文件&#xff0c;今天我们试着进一步深入学习数据驱动。 本篇文章我们讨论一下如何使用数据驱动思想实现测试。 1、数据驱动框架…

从零开始学cv-5: 图像的仿射变换

文章目录 一&#xff0c;简介&#xff1a;二&#xff0c;图像仿射变换详解2.1&#xff0c;图像平移&#xff1a;2.2 &#xff0c;图像旋转&#xff1a;2.3&#xff0c;仿射变换&#xff1a; 一&#xff0c;简介&#xff1a; 仿射变换&#xff08;Affine Transformation 或 Aff…

Lumina学术引擎免费问世,性能超谷歌学术5倍

Lumina介绍 Lumina是一款完全免费的AI学术搜索引擎&#xff0c;借助强大的数据库和高效的匹配速度。利用超过 15 种模型从超过 100 万篇期刊文章中找出最相关的来源&#xff0c;从而构建答案。搜索结果相关性平均比谷歌学术高出5倍&#xff0c;支持超1亿研究对象搜索&#xff…

8.18日学习打卡---Spring Cloud Alibaba(五)

8.18日学习打卡 目录&#xff1a; 8.18日学习打卡 RocketMQ什么是RocketMQ生产者和消费者技术架构 RocketMQ安装与配置环境搭建与测试RocketMQ管理命令 RocketMQ发送消息普通消息顺序消息之全局消息顺序消息之局部消息消费者消费消息延迟消息延迟消息代码实现单向消息批量消息过…

【HarmonyOS】云开发-用户自动认证

背景 华为云服务提供了统一认证的云服务&#xff0c;支持手机、邮箱等自定义登录服务&#xff0c;并且提供了免费使用的额度&#xff0c;这样子方便中小企业或者项目快速的开发工作。下面是支持的认证方式&#xff1a; 操作步骤 1.AGC(AppGallery Connect)创建项目 在AGC界…

C++ | Leetcode C++题解之第342题4的幂

题目&#xff1a; 题解&#xff1a; class Solution { public:bool isPowerOfFour(int n) {return n > 0 && (n & (n - 1)) 0 && n % 3 1;} };

zabbix监控进程、日志、主从状态和主从延迟

zabbix监控进程、日志、主从状态和主从延迟 监控进程1、下载服务2、编写脚本3、编写zabbix_agentd.conf4、新建监控项配置触发器5、查看邮件 监控日志1、上传log.py的2、编写zabbix_agentd.conf3、新建监控项配置触发器 监控数据库主从状态1、编写/etc/hosts&#xff08;master…

IOS 09 R.swift框架和使用方法

R.swift框架主要是实现通过类字段访问字符串&#xff0c;图片&#xff0c;等资源&#xff1b;类似Android那边通过R类访问&#xff0c;好处是有提示&#xff0c;如果缺少资源&#xff0c;直接就是编译错误&#xff1b;OC类似的功能叫R.objc。 添加依赖 添加依赖 #将资源&…

第八周:机器学习笔记

第八周机器学习笔记 摘要Abstract机器学习1. 鱼和熊掌和可兼得的机器学习1.1 Deep network v.s. Fat network 2. 为什么用来验证集结果还是不好&#xff1f; Pytorch学习1. 卷积层代码实战2. 最大池化层代码实战3. 非线性激活层代码实战 总结 摘要 本周学习对李宏毅机器学习视…

AI学习记录 - Word2Vec 超详细解析

创作不易&#xff0c;点个赞 我们有一堆文本&#xff0c;词汇拆分 sentences ["jack like dog", "jack like cat", "jack like animal","dog cat animal", "banana apple cat dog like", "dog fish milk like"…