写在之前
- 什么是线性表?
- 线性表是由n个数据类型相同的元素组成的有限序列。
- 什么是数组?
- 使用顺序存储方式实现的线性表。
- 什么是链表?
- 使用链式存储方式实现的线性表。
数组
数组特点
- 数组的每个元素在内存位置上也相邻,因此内存需要分配一大块位置用来实现数组。
- 可以在O(1)时间根据下标访问任何一个元素。
- 数组的每个结点只储存数据元素。(和链表不同,如:单链表还要储存指向下一个元素的指针。)
- 数组插入和删除操作的时间复杂度是O(n),因为需要移动大量元素。
链表
单链表
- 单链表特点
- 单链表不需要一整块的内存空间,链表的每一个结点都可以分开存储,彼此之间使用指针联系。
- 单链表查找元素的时间复杂度是O(n)。
- 单链表插入和删除的时间复杂度是O(1)。(如果算上找到要插入的位置,应该是O(n),因为单链表查找某一个元素只能从头结点开始,但是这个时间开销还是比数组插入删除少。)
- 单链表找到后继结点的时间复杂度是O(1),找到前驱结点的时间复杂度是O(1)。
- 单链表的每个结点分成两部分,数据元素和指向后继结点的指针。
- 单链表结构图
头结点的数据域不储存任何数据元素,头指针指向头结点,单链表最后一个元素的指针指向NULL。
双链表
- 为什么需要双链表概念
因为单链表有一个缺陷:访问前驱结点的时间复杂度是O(n),所以引入了双链表,双链表的每一个结点有一个prev指针指向前一个元素,有一个next指针指向下一个元素。 - 双链表特点
- 双链表不需要大块的内存空间,不会造成内存碎片。
- 双链表相较于单链表查找元素的复杂度有所下降,因为双链表因为拥有了指向前驱的指针,我们可以从头结点和尾结点同时开始查找,运用了二分法思想。
- 双链表插入和删除操作的时间复杂度是O(1)。
- 双链表的每个结点分成3部分,prev指针、数据域、next指针。(一个指针在32位操作系统中,占据4字节,在64位操作系统中,占据8字节,因此双链表比单链表需要更多内存空间,为了节省空间,一般使用单链表,以时间换空间。)
- 双链表结构图
循环链表
-
循环单链表
- 当把单链表的表尾指针指向头节点数据域,就形成了循环单链表。
-
循环双链表
- 当把双链表的表尾结点的next指针指向头结点数据域,当把头结点的prev指针指向表尾结点的数据域。
什么情况下使用数组
- 当确定元素个数的时候使用数组。
- 当需要很多次查找元素操作时使用数组。
- 当不需要经常插入、删除元素时使用数组。
什么情况下使用链表
- 当不确定元素个数时,使用链表。
- 当不需要很多次查找元素操作时使用链表。
- 当需要经常插入、删除元素时,使用链表。