这是C++算法基础-数据结构专栏的第十九篇文章,专栏详情请见此处。
引入
从这篇博客开始,我们就要正式学习数据结构了。
Q:什么是数据结构呢?
A:数据结构是在计算机中存储、组织数据的方式。小到变量、数组,大到线段树、平衡树,都是数据结构。
Q:为什么要使用数据结构呢?
A:程序运行离不开数据结构,不同的数据结构又各有优劣,能够处理的问题各不相同,而根据具体问题选取合适的数据结构,可以大大提升程序的效率。所以,学习各种各样的数据结构是很有必要的。
而链表就是一种常见的数据结构,它分为单链表和双链表,它们的区别是指针的指向。
下面我们就来讲单链表的实现。
定义
链表是一种用于存储数据的数据结构,使数组如链条一般的方法连接元素。它的特点是插入与删除数据十分方便,但寻找与读取数据的表现欠佳。
单向链表中包含数据域和指针域,其中数据域用于存放数据,指针域用来连接当前结点和下一节点。它的主要用途是储存邻接表(树与图的一种存储方式)。
过程
Tips:操作链表时,每个节点的指向的部分比较抽象,光靠文字描述和代码可能难以理解,建议配合作图来理解。
链表的实现方式通常有两种,一种是结构体+指针,一种是定义多个数组实现,而比较容易理解和代码实现的则是第二种方法,所以我们这次就要讲解用数组实现的链表。
单链表的最主要操作有三个:构建、插入(写入)数据和删除数据。
请注意:下面文字中“某一节点的下一个节点”和“某一节点所存储的下一个节点”是有区别的!“某一节点所存储的下一个节点”指的是这个节点的
中存储的下标!
构建单链表
首先需要创建两个数组:存储每个节点的值,
存储每个节点的下一个节点的下标,这两个数组是用下标关联起来的;再创建一个头结点
,刚开始它指向空节点(-1),链表中有节点后就指向第一个节点;其次还需要一个变量
,表示当前节点的下标。
向链表中插入(写入)数据
需要说明一点:链表中每个节点的下标不需要管顺序,也就是说,下标位3的节点不一定就在下标为5的节点前面。
向节点后插入一个节点的流程大致如下:
- 在
节点的
中存储数值;
- 将
节点的
存储为
节点所存储的
;
- 将
节点的
存储为
。
首先,图一展示了起始状态;然后,在新节点上面储存数据(第一步,图二);由于新节点要插在节点后,所以新节点的下一个节点要赋值为
节点所存储的下一个节点(第二步,图三);最后,
节点的下一个节点要赋值为
节点(第三步,图四)。
还有一点需要注意,操作完成后需要,以便进行下一个节点的插入。
除了向节点后插入一个节点,也有向头节点后插入一个节点(简称头插)的操作,这两者虽然代码实现有所不同,但是思路大同小异,那头插的代码就不再展示了,留给读者去思考。(删除数据也有类似操作,后面也不再讲解)
Q:上文提到定义多个数组实现比较容易,它有什么优越性呢?
A:这种方式除了代码比较简短,容易理解,再就是插入(写入)数据(创建新节点)很快。
在链表中删除数据
将节点后的节点删除,实际就是将
节点的
存储为它所存储的
所存储的
。
首先,图一展示了起始状态;然后,节点的下一个节点要赋值为
节点所存储的下一个节点所存储的下一个节点(第一步,图二)(这句话好像绕口令o((⊙﹏⊙))o)。
细心的人可能能发现,在图中下标为2的节点,经过删除操作后,已经没有用了,但是还是占用着内存,这样会不会有问题呢?
实际上,算法题目的内存限制很大,一般不需要管被删除的节点下标,在工程上我们才需要注意(这种情况是使用动态链表实现的,删除后就自动释放内存了)。
我们可以看出,虽然空间浪费了,但是时间复杂度比自动释放内存的动态链表要快,这种方法称为空间换时间。
性质
这里,我们通过链表与数组之间的区别来理解链表的性质。
链表和数组都可用于存储数据。与链表不同,数组将所有元素按次序依次存储。不同的存储结构令它们有了不同的优势:
链表因其链状的结构,能方便地删除、插入数据,操作次数的时间复杂度是的。但也因为这样,寻找、读取数据的效率不如数组高,在访问数据中的时间复杂度是
的。
数组可以方便地寻找并读取数据,在访问数据中的的时间复杂度是的。但删除、插入的时间复杂度是
的。
代码
下面给出单链表的实现代码:
int head,e[N],ne[N],idx;
void init(){
head=-1;
idx=0;
}
void add(int k,int x){
e[idx]=x;
ne[idx]=ne[k];
ne[k]=idx++;
}
void remove(int k){
ne[k]=ne[ne[k]];
}
代码解释
第一行的各种变量和数组已经在前面讲解了,这里不再详细讲解;init()函数的作用是初始化;add()函数的作用是将插到下标是
的节点后面;remove()函数的作用是将下标是
的节点后面的节点删掉。
上一篇- C++算法基础专栏文章 下一篇-
每周六更新一篇文章,内容一般是自己总结的经验或是在其他网站上整理的优质内容
点个赞,关注一下呗~