LFU缓存算法思路以及代码

进阶6 00.01.07 开始

LFU根据频度来决定,如果操作的次数比较低,那么进行替换。
如果两个key 频度一样,且都是操作的次数最低的,那么最不经常访问的出局。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
下面挂载着的具体key值,也是一个双向链表

00.08.52

经过几次操作,第二次节点下面没有了,此时删去第二次的节点。
若继续对c进行操作,则继续 新建立 第二次的节点。

执行put时,先检查有没有key
如果没有的话,新建节点1

执行get时,先检查有没有key
如果没有,返回null

如果有的话,先找到其是 挂载在哪个(代表次数的)头节点上,
将key拿出来后,将key上下的节点 重连
在这里插入图片描述
然后检查是否存在 头节点+1,如果有,将key 挂载在其最后一项,
如果没有,先创建一个,将key 挂载在其最后一项
在这里插入图片描述
例子:
A执行2次,B执行2次,c执行4次
在这里插入图片描述
先删A。

代码:

代码地址:J:\牛网 算法进阶班第4期课程(已完结)\课件 & 代码\新进阶课第3、4节代码\advanced_class_04\code_03_LFU
如何描述这些小链表。
在这里插入图片描述
在这里插入图片描述
图中,up,down表示这个双向链表上面、下面分别是啥。
在这里插入图片描述
这个整体如何表示呢?
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
给我node,来初始化nodelist
在这里插入图片描述
把节点移至头部:
之前的头部变成新头的下一个,即newHead.down=head
老头的上一个变为newHead

在这里插入图片描述
检查是否为空:
在这里插入图片描述
下图以及如下代码表示,当get(b)发生时,如何删除一个节点:
在这里插入图片描述
在这里插入图片描述
00.23.17
if条件满足,说明nodelist中没有节点
这里来看,要删的节点是不是头节点
在这里插入图片描述
要删的节点是不是尾结点
在这里插入图片描述
要删的节点 既不是头节点 又不是尾结点。
在这里插入图片描述

接下来用node和node list来拼凑 LFUCache

大结构是好多nodelist(表示出现次数1,2,3)串起来的,nodelist下面挂着很多list

capacity表示 key 的个数超过多少,开始删节点。
size表示现在实际放了多少个。
在这里插入图片描述
record表示一个key对应的实际node是啥 key–>node
heads表示任何一个node都能查到其是属于 哪一个nodelist
在这里插入图片描述
headlist表示所有nodelist的头部(次数最低),下面挂着次数最低的各个节点
在这里插入图片描述
初始化 LFUCache
在这里插入图片描述
下面讲解set方法:
先在record中查key是否存在,
if条件满足时,如果存在了,则在record中把node的内存地址 拿出来。
node.value=value表示把value赋值给节点的value
move是一个黑盒,功能是:分离所在的nodelist,把该node移到下一个+1的nodelist上
在这里插入图片描述
else的第一个if
如果size已经到了阈值,则应该删掉一个节点才能接着挂上。
删除 headlist.tail这个节点。 即headlist的尾结点。
然后在headlist中调用deletenode
modify head list 表示如果head list 中没有节点,则把整个 nodelist删掉
然后移除node中的key值
heads是一个节点对nodelist的关系

总之,蓝色代码表示,找到该删的节点,删掉,并消除其影响
在这里插入图片描述
在这里插入图片描述
一个新的key,value进来,词频为1,作为这个新的node
如果整个大链表 headList 为空
则新的key,value 是大链表的第一个节点,则新建headList=new node list
否则,headlist存在,进来过东西
如果当前头部的次数等于1(headlist中head中的times 表示整个链表是词频为times 的链表),例子:
headlist中head中的times 即B中的times,为1,表示这个是词频为1的链表
如果有一个1词频的节点,则新加入的D直接放入
如果没有一个1词频的节点,则先需加入1词频的链表中的节点。
在这里插入图片描述
然后把key,node放入record中,


在这里插入图片描述
这就是set的全部:
在这里插入图片描述
在这里插入图片描述
key如果曾经进来过,则在record中一定有记录。
如果之前有过,则取出这个node,修改值(为啥呢????),次数+1,取得其所在的链表是哪一个。把node从其目前所在的链表分离,挂在下一个词频上。

如果key是新的,即当前大小size已经超过容量,那么应该删掉词频最低的链表中 尾部节点。
先把要删的尾部节点 拿出来。然后在headlist 中把其删掉,
删掉该节点之后,如果整个链表中没有东西,则把整个链表都删掉,

总之,这个if表示,容量到达顶峰时,删掉该删的节点,并删除其影响。
在这里插入图片描述
对于下面这一段,
99行 headlist.head.times 表示词频为times
headlist.head.times.equals(node.times)表示node的times是否
在这里插入图片描述
其中这一段表示,
切换headlist,
在这里插入图片描述
把headlist从2切换成1.
在这里插入图片描述
实现换头:
新头的下一个指向老头
老头的上一个指向新头
headlist指向新头

get实现由key找value
在这里插入图片描述
因为进行了get操作,所以node.times要++

讲modify headlist
即delete之后,要不要删掉链表
在这里插入图片描述
00.56.16
讲move方法:
关于preList 和 oldNodeList 方法,
对b执行操作时,应该是3到6之间生成5,4被拿掉,
若此时4中没有数了,则5的前一个链表为3。
若4中还有数,则5的前一个链表为4。

preList 即表示 新链表的前一个数(即新链表应该挂在哪一个节点上)
如果删除成功,modifyHeadList(oldNodeList)为1,则preList 为 oldNodeList.last即oldNodeList的上一个节点。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值