维基百科:链表(Linked list)是一种常见的基础数据结构,是一种线性表,可是并不会按线性的顺序存储数据,而是在每个节点里存到下一个节点的指针(Pointer)。因为没必要须按顺序存储,链表在插入的时候能够达到O(1)的复杂度,比另外一种线性表顺序表快得多,可是查找一个节点或者访问特定编号的节点则须要O(n)的时间,而顺序表相应的时间复杂度分别是O(logn)和O(1)。html
为了更好的理解链表,咱们拿数组来做对比。数组
相比数组,链表是一种稍微复杂一点的数据结构。从底层的存储结构上来看:数组须要一起连续的内存空间,堆内存的要求比较高,若是咱们申请一个100MB大小的数组,当内存中没有连续的、足够大的空间的时候,即使内存的剩余总可用空间大于100MB,仍然会申请失败;而链表偏偏相反,它并不须要一起连续的内存空间,它经过“指针”将一组零散的内存块串联起来,因此若是咱们申请100MB大小的链表,若是没有100MB连续的内存空间,且内存的剩余总可用空间大于100MB,根本不会有问题。数据结构
使用链表结构能够克服数组链表须要预先知道数据大小的缺点,链表结构能够充分利用计算机内存空间,实现灵活的内存动态管理。可是链表失去了数组随机读取的优势,同时链表因为增长告终点的指针域,空间开销比较大。yii
链表的基本结构以下:指针
链表结构五花八门,可是咱们只介绍最经常使用的三种,分别是:单向链表,单向循环链表,双向循环链表。
(若是你想进一步了解这些结构,能够点击下方的传送门)htm
因为在链表中,仅仅只有头节点和尾节点是可见的,所以要想查找某个节点,必须从头节点或尾节点一路找下去,时间复杂度至少为O(logn) (二分),不如数组快。blog
... | 数组 | 链表 |
---|---|---|
访问 | O(1) | O(N) |
搜索 | O(N) | O(N) |
插入 | O(N) | O(1) |
删除 | O(N) | O(1) |
实际上,链表插入和删除元素的时间复杂度均为O(N)。为何呢?由于虽然插入和删除元素的操做是O(1)的没错,可是要想插入或删除节点,你必须得知道节点在哪,获取节点的操做是O(N)的,
所以总的时间复杂度为O(N)。尽管如此,链表插入删除元素的速度依旧是要优于数组的。内存
链表适合存储对元素查找,访问要求低;可是对删除,插入要求高的数据。get