首先来说一个问题,线性表和链表的区别。
线性表是n个数据元素的有限序列,复杂的线性表中,数据元素可以有若干个数据项构成一个记录。线性表可以有两种表示方式,顺序表示和链式表示。线性表的顺序表示是用一组连续的内存存储线性表的数据元素。而线性表的链式表示是用随机的存储单元来存储线性表的元素,这种线性表就是链表。链表的结点包含两个域,存储数据元素信息的数据域和存储直接后继存储位置的指针域。顺序表示和链式表示各有优点,他们的区别类似于模板库里的vector和list。顺序表示可以顺序存储,因此它可以轻松的访问第i个数据元素和求出表的长度,但是插入和删除却很麻烦,因为除了结尾其余位置的插入和删除都必须移动一部分元素。插入和删除的时间复杂度是O(n)。而链表由于其随机存储的结构,可以方便的插入和删除,但是求链表的长度,就必须遍历整个链表。链表只存储头结点的信息,这个链表占用的空间不需要预先分配划定,可以根据需求随时生成,因此链表是一种动态结构。
今天的链表我就不做过多总结,原因是链表是c语言里的结构,在c++里链表可以用vector和list实现,基本操作都可以很方便的实现。指针也是c语言里的重点,c++用了更安全的引用和迭代器来代替指针的功能。但这不代表链表这种数据结构不重要,而是我们有更好的方法来表达和使用链表。而我这个数据结构系列的博客是对我之前写的剑指offer系列博客中所用到的数据结构的总结。而剑指offer中的链表大多是用指针做的,因此这里就不做过多讨论了。
还有,c语言中的功能用函数和结构体实现,而在c++中使用了更安全和面向对象的类实现。因此c++中要多使用具有面向对象特征的类来实现功能,类比普通的函数更安全,更容易扩展和维护。
还有一个问题是vector和list的区别。
这个问题可以参考上一个回答,但这问题我总结成以下几点:
1. 总体来讲:vector是可变大小的数组,存放在一段连续的内存上;而list是双向链表,逻辑上相邻的元素其物理内存可能相邻也可能不相邻。它们都是顺序容器。
2. 访问:vector支持快速随机访问,而list只支持双向顺序访问。
3. 插入与删除元素:vector除了尾部之外的位置插入或删除很慢,单list在任何位置插入删除都很快。
4.内存:由于涉及额外指针的维护,list的额外内存开销更大。
5.迭代器类型不同:vector提供随机迭代器(random_access_iterator
),list提供的是双向迭代器(bidirectional_iterator
)。区别是随机迭代器可以支持下标操作,双向迭代去可以支持双向的指针操作。
链表在剑指offer上的相关题目有:
5,13,26-27,37,56-57
相关考点:
快慢指针
链表的遍历,从前都后,从后向前(逆序输出)
插入,删除。查找(O(1))
两个有序链表的合并,有共同链表结点查找
存在环的链表如何查找环,环的长度。双向链表。