数据结构【C++】(一)


数据结构(一)

提示:这里可以添加本文要记录的大概内容:

数据结构是算法的基础,好的数据结构可以大大提升算法的时间和空间复杂度。数据结构大致可分为线性结构(如数组、链表、队列、栈等),非线性结构(树、图等)。下面将会逐次介绍这些数据结构的含义、操作以及C++用法。


提示:以下是本篇文章正文内容,下面案例可供参考

一、数组和链表

1.1 数组

数组是最简单的线性结构之一,数组的元素地址按照顺序存储,一维数组可以按照C语言中的数组的生成方式。

auto a[10];

c++中提供可变长类型的数组,其使用和维护起来更加方便,推荐使用。

vector<int> v;

数组的常用操作:
1. 创建数组 vector<int> a;
2. 添加元素 a.emplace_back();
3. 访问元素
4. 修改元素
5. 删除元素
6. 遍历数组
7. 查找元素
8. 数组的长度
数组排序(内置的排序算法)

【增删改查的时间复杂度】:
访问:O(1) 直接按照下标索引即可
搜索:O(N) 需要逐个访问
删除:O(N) 删除元素需要将被删元素后面的元素逐次移动上来,保证依然是一个顺序表
插入:O(N) 插入元素后的元素需要逐次向后移动,保证依然是一个顺序表

1.2 链表

链表也是一种较为简单的线性数据结构,其特点是元素的内存地址不连续,需要靠指针指向下一个连接的元素,像一条链条一样串起来,故称为“链表”。
链表有单向链表和双向链表,单项链表是只有一个指针指向下一个节点,双向链表是有两个指针分别指向前后节点,下面仅介绍单向链表【双向链表实现类似】。

 struct ListNode {
    
    
	int val;
	ListNode *next; //指向下一个节点
	ListNode() : val(0), next(nullptr) {
    
    } //无参构造函数
	ListNode(int x) : val(x), next(nullptr) {
    
    } //有参构造函数
	ListNode(int x, ListNode *next) : val(x), next(next) {
    
    } //有参构造函数
  };

【增删改查的时间复杂度】:
访问:O(N) 需要从头节点依次寻找,直到找到该元素
搜索:O(N) 需要逐个查找比较,同访问类似
删除:O(1) 仅需要将被删节点的指针与下个节点断开,并连接被删节点的上个节点和下个节点
插入:O(1) 删除的逆操作

注意:虽然删除和插入的操作的时间复杂度很低,但是在实际应用中,如果不知道在哪里插入和删除,仍需要花费 O(N) 的时间先搜索到该元素。

二、队列与栈

2.1 队列

队列是先入先出的数据结构,和我们实际中的排队行为类似。队列有单端队列、双端队列、优先队列,循环队列等等,本文仅介绍单端队列,其他队列会在后续文章介绍。
C++中有已经实现单端队列的头文件,可以直接使用。

#include <queue>
queue<int> q;

【增删改查的时间复杂度】:
访问:O(N) 需要从队头节点依次寻找,直到找到该元素
搜索:O(N)
删除:O(1) 仅能删除队头元素 俗称“出队”
插入:O(1) 仅能在队尾插入 俗称“入队”

注意:队列的搜索和访问是一边出队,一边搜索和访问。

2.2 栈

栈和队列相反,是先入后出的数据结构。栈有单调栈等变体,本文介绍最简单的栈结构。
C++中有已经实现单端队列的头文件,可以直接使用。

#include <stack>
stack<int> st;

【增删改查的时间复杂度】:
访问:O(1) 仅能访问栈顶元素
搜索:O(N)
删除:O(1) 栈顶元素 “弹栈”
插入:O(1) 向栈顶“压栈”

注意:栈的搜索是一边弹栈,一边搜索。


猜你喜欢

转载自blog.csdn.net/weixin_45667108/article/details/123779170