链表相关知识点

1.缓存是什么?

  • 缓存是提高数据读取性能的技术,在硬件和软件开发中有着非常大的应用。当缓存大小有限的时候,哪些数据应该保留这就需要缓存淘汰策略来决定。
  • 常见的策略
    1.先进先出的策略
    2.最少使用策略(LFU)
    3.最近最少使用策略(LRU)
  • 缓存是用空间换时间的例子。在硬盘的数据每次都会询问一次硬盘会比较慢。实现将数据加载在内存中,虽然会耗费内存空间但是每次查询的速度就会大大提高。

2. 数组与链表

  • 数组一旦声明就会占用连续内存空间。如果声明的数组出现不够用的时候,只能去申请一个更大的空间,将原数组拷贝进去。
  • 链表本身没有大小的限制,天然地支持动态扩容。
  • 数组简单易用,在实现上使用的是连续的内存空间,可以借助cpu的缓存机制,预读数组中的数据,所以访问效率更高。然而链表在内存中并不是连续存储,对cpu缓存不友好,没办法有效预读。

循环链表和双向链表

*循环链表和单链表的区别在于尾节点,单链表的尾节点指向空地址。循环链表比较适合处理环形结构的数据。
*双向链表:需要两个空间来存储后继结点和前驱结点的地址。如果存储相同多的数据,双向链表比单链表占用更多的内存空间。

3.基于链表实现LRU缓存淘汰算法?

思路:维护一个有序单链表,靠近链表尾部的节点是越早之前访问的。当有一个新数据被访问时,我们从链表头开始遍历链表。

1.如果此数据之前已经被缓存在链表里面了,我们遍历这个数据对应的节点并将其从原来的位置删除,然后插入到链表的头部。
2.如果此数据没有在缓存链中,又可以分为以下两种情况:

  • 如果此时缓存没有满,则将此节点直接插入到链表的头部
  • 如果此时缓存已满,册从链表为波删除节点,将新的数据节点插入到链表的头部。

4.链表类代码的技巧

  • 理解指针和引用的含义:指针中存储了这个变量的内存地址,指向了这个变量,通过指针就能找到这个变量。
  • 警惕指针丢失和内存泄露:对于c语言而言,删除链表节点的时候,一定要记得手动释放内存空间。
  • 利用哨兵简化实现难度:针对链表的插入、删除操作,需要对插入第一个结点和删除最后一个结点的情况进行特殊里。有哨兵结点的链表叫做带头链表。没有哨兵结点的链表叫作不带头链表。
  • 重点留意边界条件处理
  1. 链表为空,代码是否能正常工作 2.链表只有一个结点,代码能否正常工作
    3.链表只有两个结点是,代码能否正常工作
    4.代码逻辑在处理头结点和尾节点的时候,是否能正常工作。
//递归方式实现链表反转
Node * reverseList(List head)
{
    //如果链表为空或者链表中只有一个元素
    if(head == NULL || head->next == NULL)
    {
        return head;
    }
    else
    {
        //先反转后面的链表,走到链表的末端结点
        Node *newhead = reverseList(head->next);
        //再将当前节点设置为后面节点的后续节点
        head->next->next = head;
        head->next = NULL;
        
        return newhead;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值