数据结构与算法之美4---链表上

五花八门的链表结构

重点介绍最常见的链表结构:单链表,双向链表和循环链表。
内存分布
链表的存储不需要连续的内存空间,通过指针将一组零散的内存块串联起来使用,而内存块则称为链表的“接点”。

单链表

单链表
单链表的头结点用来记录链表的基地址,尾接点不是指向下一个结点而是指向一个空地址NULL,表示这是链表上最后一个结点。

单链表的插入和删除结点

在这里插入图片描述
由上可知,链表的插入和删除复杂度为O(1),而随机访问复杂度为O(n)。

循环链表

循环链表
循环链表的优点hi链尾到链头比较放标

双向链表

双向链表
双向链表可以支持O(1)时间复杂度的情况下找到前驱结点

  1. 删除给定指针指向的结点
    双向链表比较方便,复杂度为O(1),同理在链表的某个指定结点前面插入一个基点,复杂度也为O(1)
  2. 对于有序链表,双向表的按键值查询效率也比单链表高,可以记录上次查找的位置p,每次查找的值与p比较,决定往前还是往后查找,平均只需要查找一半的数据
    实际开发中,LinkedHashMap底层就是用的双向链表

双向循环链表

双向循环链表

课后题:

  1. 思考给予链表实现LRU缓存淘汰算法
    我的思路是这样的:我们维护一个有序单链表,越靠近链表尾部的结点是越早之前访问的。当有一
    个新的数据被访问时,我们从链表头开始顺序遍历链表。
    如果此数据之前已经被缓存在链表中了,我们遍历得到这个数据对应的结点,并将其从原来的位
    置删除,然后再插入到链表的头部。
    如果此数据没有在缓存链表中,又可以分为两种情况:
    如果此时缓存未满,则将此结点直接插入到链表的头部;
    如果此时缓存已满,则链表尾结点删除,将新的数据结点插入链表的头部。
    这样我们就用链表实现了一个 LRU 缓存,是不是很简单?
    现在我们来看下 m 缓存访问的时间复杂度是多少。因为不管缓存有没有满,我们都需要遍历一遍链
    表,所以这种基于链表的实现思路,缓存访问的时间复杂度为 O(n)。
  2. 如何判断一个字符是否是回文字符串,如果字符串是通过单链表来存储
    Ans: 思路
    使用快慢两个指针,快指针一次前进两步,慢指针每次前进一步,且前进的过程中,将慢指针走过的结点逆序,当快指针到尾部,慢指针到了中点,判断前半部分和后半部分是否相等即可还需要注意,指针是奇对称和偶对称的情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值