链表(上)

数组与链表

数组需要一块连续的内存空间来存储,对内存的要求比较高,如果我们申请一个100M大小的数组,当内存中没有连续的、足够大的存储空间时,即便内存剩余的总空间大于100M,仍然会存储失败。
链表并不需要一块连续的内存空间,它通过“指针”将一组零散的内存块串联起来使用,所以如果我们申请的是100M大小的链表,根本不会有问题。

三种最常见的链表结构

单链表.jpg

链表通过指针将一组零散的内存块串联在一起,内存块称为链表的结点,为了将所有的结点串起来,每个链表的结点除了存储数据之外,还需要记录链上的下一个节点的地址。我们把记录下一个结点地址的指针叫做后继指针。
头结点:用来记录链表的基地址。有了它,就可以遍历整条链表。
尾结点:指针不是指向下一个结点,而是指向一个空地址NULL,表示这是链表上最后一个结点。

插入删除节点.jpg

在链表中插入或删除一个数据,并不需要为了保持内存的连续性而搬移结点,因为链表的存储空间本身就不是连续的。所以,在链表中插入和删除数据是非常快速的。
针对链表的插入和删除操作,我们只需要考虑相邻结点的指针改变,所以对应的时间复杂度是 O(1)
链表想要随机访问第k个元素,就没有那么高效了,需要根据指针一个结点一个结点依次遍历,直到找到相应的结点。

循环列表.jpg

循环链表与单链表的区别就在于尾结点,尾结点指针指向链表的头结点。
循环链表的优点是从链尾到链头比较方便,当需要处理的数据具有环型结构特点时,特别适合采用循环链表。
双向链表.jpg

双向链表,支持两个方向,每个结点不止有一个后继指针next指向后面的结点,还有一个前驱指针prev指向前面的结点。

LRU(Least Recently Used),最近最少使用策略。
维护一个有序单链表,越靠近链表尾部的结点,是越早之前被访问的,如果有一个新的数据被访问,我们从链表头开始顺序遍历链表。
1、如果此数据之前已经在缓存链表中,遍历得到这个数据对应的结点,并将其从原来的位置删除,然后再插入到链表的头部。
2、如果此数据之前没有缓存在链表中,又可以分为两种情况:
-如果此时缓存未满,则直接插入链表的头部。
-如果此时缓存已满,则链表尾结点删除,将新的数据结点插入链表头部。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容