三、链表

链表和数组的区别

单链表

数组:连续的内存空间
链表:通过“指针”将一组零散的内存串联起来(单链表,双向链表,循环链表)
在这里插入图片描述

内存块称为链表的“结点”,为了把所有的节点串联起来,每个链表的结点除了存储数据,还会记录链上的下一个结点的地址,这个记录结点地址的指针叫 后继指针 next。
在这里插入图片描述

第一个结点叫头结点,最后一个是尾结点,尾结点指针指向空地址(这是为了防止尾结点的后继指针next 成为一个野指针,导致遍历链表停不下来,或者出现一堆本不属于该链表的垃圾数据等)

插入、删除

• 插入、删除一个结点,只要改变相邻的结点的指针就可以
• 插入、删除:在上一节点的后继指针指向新结点地址,新结点的后继指针指向下一个结点的地址
• 插入,删除结点时间复杂度 O(1)
• 删除某个结点的值等于某个给定值 时间复杂度为 O(n)
在这里插入图片描述

查询

• 访问第 K 个元素需要遍历
• 最好时间复杂度O(1)
• 最坏时间复杂度O(n)
• 平均时间复杂度O(n)

循环链表和双向链表

循环链表

• 循环链表是一种特殊的单链表,他的尾结点指针指向链表的头结点
• 使用场景适合具有环型结构的数据
在这里插入图片描述

双向链表

• 每个结点有两个指针,一个是前驱指针 prev 指向前面的结点,一个是后继指针 next 指向后面的结点
• 需要额外的两个空间来存储前驱结点和后继结点
• 支持双向遍历
• 浪费空间
• 插入,删除 O(1)
在这里插入图片描述

从链表中删除数据:

• 删除结点中“值等于某个给定值”的结点。 这种删除方法需要遍历整个链表,所以时间复杂度为O(n)
• 删除给定指针指向的结点 双向链表是O(1),单链表是O(n),单链表在删除给定指向指针的结点需要找到该结点的前置结点,但是前置结点需要遍历才能找到,遍历时间复杂度为O(n)

链表中添加数据:

• 和上面的操作相同
空间换时间
总结:
空间换时间:对于执行较慢的程序,通过消耗更多内存来优化
时间换空间:对于消耗内存过多的程序,通过消耗更多的时间来降低内存的消耗

双向循环链表

在这里插入图片描述

链表和数组性能对比

在这里插入图片描述

数组和链表的区别

• 数组优点:使用连续的内存空间,可以借助CPU的缓存机制,预读数组中的数组,访问效率较高
• 数组缺点:是大小固定,一经申明就要占用整块连续内存空间,如果声明数组过大,系统没有足够内存空间分配,会导致内存不足,如果声明内存过小,出现不够用,又要申请一个更大的内存空间,把愿数组拷贝过去,耗费时间
• 链表缺点:在内存中并不是连续存储,所以对CPU缓存不友好,没法有效预读
• 链表优点:没有大小限制,支持动态扩容

LRU

思路:
• 使用定长链表来保存所有缓存的值,并且最老的值放在链表最后面 当访问的值在链表中时: 将找到链表中值将其删除,并重新在链表头添加该值(保证链表中 数值的顺序是从新到旧) 当访问的值不在链表中时: 当链表已满:删除链表最后一个值,将要添加的值放在链表头 当链表未满:直接在链表头添加
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值