链表与数组
- 链表定义: 百度百科
- 数组定义:百度百科
总结:
链表和数组最大差别是在内存空间结构上,连续(数组)和可非连续(链表)。数组通过内存地址和下标可以快速找到内存存储位置,链表是通过节点(指针)指向前后的地址一个个去查找。
电影座位比喻:
数组:一排座位标注了有顺序的123..编号。
链表:每个座位位置上记录了下个和上个位置的坐标。
查找:
数组座位: 数组来的直接,可以数数找位置,不用一个一个看。
链表座位: 我们找位置就必须从第一个座位开始找,找到它指向的下一个座位的坐标,然后再找到下一个看第二个座位的下一个是哪个座位...依次找到自己的位置。
-----数组查找速度快
添加座位:
数组座位:数组就需要新增空间,然后挪动插入当前需要插入的位置后所有位置向后移动(麻烦)。
链表座位:链表结构只需要找到需要加入的位置,修改标记指向即可(轻松)。
---- 链表插入快(删除同理)
链表细分
-
单链表:单向节点指向
-
双向链表:
-
循环链表:
-
双向循环链表:
区别:
单链表和双向链表的叙别主要是链表节点是否指向一边。
循环和非循环链表主要区别在于首尾是否互相指向。
缓存
缓存常见淘汰策略:
常见的策略有三种:先进先出策略 FIFO(First In,First Out)、最少使用策略 LFU(Least Frequently Used)、最近最少使用策略 LRU(Least Recently Used)
链表结构实现(摘抄自:极客时间)
我的思路是这样的:我们维护一个有序单链表,越靠近链表尾部的结点是越早之前访问的。当有一个新的数据被访问时,我们从链表头开始顺序遍历链表。
- 如果此数据之前已经被缓存在链表中了,我们遍历得到这个数据对应的结点,并将其从原来的位置删除,然后再插入到链表的头部。
- 如果此数据没有在缓存链表中,又可以分为两种情况:
如果此时缓存未满,则将此结点直接插入到链表的头部;
如果此时缓存已满,则链表尾结点删除,将新的数据结点插入链表的头部。
(数组思想同上一样)
自我思考:
如果是我从链表和数组中选择一种数据结构做缓存处理,我偏向于数组结构。1. 数组结构特点查询遍历快。原因: 既然是做缓存,那么本身做缓存的目的是什么?是为了多次访问相同数据更快,正好是数组的特点吧,访问快。 2. 缓存也存在加入和淘汰。 其实真的做缓存这个是可以一定程度上减少开销的。比如:通过估量缓存大小初始化足够或者相对接近的数组大小,减少加入缓存数据多次扩展数组,减少开销。(才疏学浅,敬请指教)