这节来说下顺序表和链表
【前言】:
1、什么是线性结构:n个数据元素的有序集合
1)集合中必存在唯一的“第一个元素”
2)集合中必存在唯一的“最后一个元素”
3)除第一个元素外,其他的元素都只有一个后继
4)除最后一个元素外,其他的元素都只有一个前驱
2、线性表
1、顺序表
1.1定义:
把线性表中的节点按照逻辑次序存储在一组连续的地址单元中,在计算机中以数组的形式保存的线性表。
1.2性质:
1.3类型定义:
#define MAXSIZE 100 //表空间的大小可根据实际需要而定,这里假设为100
typedef int DataType;
typedef struct SeqList
{
DataType array[MAXSIZE];//存放表结点
size_t _size;//有效元素的个数
}SeqList;
1.4特点
2、链表
1.1定义:
1.2性质
1.3类型定义
typedef struct Node
{
DataType data; //存储的数据
struct Node* pNext; //指向下一个节点
}Node;
3、顺序表和链表的比较
1) 空间的开辟,顺序表一般是连续的开辟一段空间,然后进行数据的增删改查,因此空间大小是固定的(静态顺序表),而链表是实时的进行节点的申请和删除,所以空间是动态的,不固定大小。(动态顺序表是为了弥补静态顺序表的缺陷,空间还可以进行扩容)
2) 当我们不知道要存储多少数据的时候,使用顺序表会造成空间的浪费,而链表是需要一个数据才申请一个节点,比起顺序表来说能在一定程度上节省空间。但是当我们知道要存储多少数据的时候使用顺序表最好,不会造成空间的浪费,而使用单链表就会造成内存碎片。
3)对CPU高速缓存的影响:
因为顺序表的空间一般是连续开辟的,而且一次会开辟存储多个元素的空间,所以在使用顺序表时,可以一次把多个数据写入高速缓存,再写入主存,顺序表的CPU高速缓存效率更高,且CPU流水线也不会总是被打断;而单链表是每需要存储一个数据才开辟一次空间,所以每个数据存储时都要单独的写入高速缓存区,再写入主存,这样就造成了,单链表CPU高速缓存效率低,且CPU流水线会经常被打断。
从这儿看,貌似顺序表要更好一些,真是如此吗?继续看下去。
②、时间上的比较(Time)
a. 访问随机元素的时间复杂度:
因为顺序表的结构就像是数组一样,可以用下标来访问它的元素,所以它的元素是支持随机访问的;相比之下,单链表的数据是链式存储的,它的元素是不支持随机访问的,想要知道某个元素,只能从头结点开始遍历整个链表,知道找到了该元素为止。因此顺序表访问随机元素的时间复杂度是O(1),而单链表访问随机元素的平均时间复杂度是O(n)。
b. 随机位置插入、删除元素的时间复杂度:
因为顺序表的元素是连续存储的,因此要在特定位置插入、删除元素需要把它之后的元素全部后移或前移一个元素的位置,时间开销很大;而单链表在插入或删除元素时,只需要改变它的前驱元素及插入或删除元素的指向即可。因此,顺序表在插入随机位置插入、删除元素的平均时间复杂度是O(n),单链表在插入随机位置插入、删除元素的时间复杂度是O(1)。
综合上述所言,顺序表和单链表各有各的优缺点,使用哪一种会好一些要结合具体的问题而言,不能一概而论。
比如:
在查询操作使用的比较频繁时,使用顺序表会好一些;在插入、删除操作使用的比较频繁时,使用单链表会好一些。