一、概念
线性表是在逻辑意义上连续的一种组织数据的方式,以其在物理存储上的不同分为顺序表和链表。
二、分类
1、顺序表
顺序表一般是以数组或者说是矢量容器这样的在内存上连续的方式来存放数据,它可以以下标快速随机的读写数据,但是在增加或删除数据是比较麻烦,其连续的特征要求在增删中间数据时必须把其后边的所有数据都挪动一下,造成了时间上的浪费。
2、链表
链表以结构体或者类为基础来实现,用结构体或类来定义节点,在节点的定义中至少包含一个此类型的指针用来指向它的下一个节点,多个节点以此方式连接在一起构成了链表,链表又分为单链表,双链表,循环链表,以及循环双链表等,其原理如下图。
我们说一说最基本的单链表和涵盖所有的双向循环链表,单链表的最经典插入和删除操作代码如下,
//在p节点后面插入s节点
s->next = p->next;
p->next = s;
这两句代码不能反着写,原因是p->next = s
会导致原来p后边的所有节点无指针引用而导致内存泄漏。
//删除p节点后边的s节点
p->next = s->next;
free(s);
单链表的缺点是尾部插入时必须循环找最后一个节点,循环链表解决了这个问题,单链表不能通过一个节点找到它的前一个节点,双链表解决了这个问题,而融合了这两大优点的双向循环链表可谓是能上天,能入地,能往前跑,能往后退,还能把头连到屁股上去,干好多事情都节省了不少时间。我们再来看看其最基本的插入和删除语句.
//在p的后面插入s
//首先为s找到前驱和后继
s->next = p->next
s->prev = p;
//将s的前驱后继指到s上
s->prev->next = s;
s->next->prev = s;
//删除p节点
p->prev->next = p->next;
p->next->prev = p->prev;
free(p)
我自己认为删除代码中前两句是很优美且经典的,大家可以好好揣摩。
三、总结
说了这么多,大多说的是链表的优点,事实也是如此,但是到了实际应用的时候我们还是要视实际情况来选择,如果数据以插入删除等变更为多,选链表比较节省时间,但是如果数据的读取比较多,那肯定是选择顺序表了。