线性表 线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串等,线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。 1.顺序表 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。 顺序表一般可以分为: 1)静态顺序表:使用定长数组存储。

typedef struct seqlist
{
 DataType array[N]; // 定长数组
 size_t size; // 有效数据的个数 
}seqlist;

2)动态顺序表:使用动态开辟的数组存储。

typedef struct seqList
{
 DataType* array; // 指向动态开辟的数组
 size_t size ; // 有效数据个数
 size_t capicity ; // 容量空间的大小
}seqlist;

静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小。 2.链表 链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。实际中链表的结构非常多样,如单向、双向;带头、不带头;循环、非循环,但是我们实际中最常用还是两种结构: 1)无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构,如哈希桶、图的邻接表等等。 2) 带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了。 顺序表和链表的区别和联系 顺序表的优点是空间连续、支持随机访问,缺点是中间或前面部分的插入删除时间复杂度O(N),并且增容的代价比较大。 链表:由于其以节点为单位存储,不支持随机访问,所以任意位置插入删除时间复杂度为O(1),没有增容问题,插入一个开辟一空间。 3.栈 栈是一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。出栈:栈的删除操作,出数据也在栈顶。 4.队列 队列只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)。入队列:进行插入操作的一端称为队尾。出队列:进行删除操作的一端称为队头。 **栈和队列的实现一般都可以使用数组或者链表实现。**栈使用数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。而队列使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。