LRU,最近最少使用算法,即当要对数据进行淘汰时,将最近最久未使用的数据淘汰,是一种缓存淘汰算法。
解题思路如下:
1)插入的结点不在内存中,缓存未满,则将此结点直接插入到链表的头部;
2)插入的结点不在内存中,缓存已满,则链表尾结点删除,将新的数据结点插入链表的头部;
3)插入的结点在内存中,将该结点删除,并放置于链表的头部。
class LinkNode{
int value;
LinkNode next;
}
public class LRU {
public static int length = 3;
public static LinkNode L;
public static void main(String[] args) {
int[] nums = {7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1}; // 访问的结点值顺序
L = new LinkNode(); // 创建头结点
L.value = 0;
int result = 0; // result=-1 表示结点不在内存中,result=length 表示缓存满了
for(int i=0; i<nums.length; i++) {
result = inLink(L, nums[i]); // inLink() 判断插入的结点是否在内存中,并返回 result(函数后面会具体介绍)
if(result != -1) {
if(result == length){
deleteLast(L); // 插入的节点不在内存中,且缓存已满,删除链表最后一个结点
}
insertHead(L, nums[i]); // 将结点插入链表头部
}
print(L.next); // 打印链表
}
}
public static int inLink(LinkNode Link, int element) { // 判断插入的结点是否在内存中,在就删除该节点并将该结点插入头部
LinkNode p = Link;
int count = 0;
while(p.next != null) {
if(p.next.value == element) {
p.next = p.next.next;
insertHead(Link, element); // 将结点插入链表头部
return -1;
}
p = p.next;
count++;
}
return count; // 返回缓存中结点的数目
}
public static void deleteLast(LinkNode Link) { // 删除尾结点
LinkNode pre = Link, p = pre.next;
while(p.next != null) {
pre = p;
p = p.next;
}
pre.next = null;
}
public static void insertHead(LinkNode Link, int element) { // 将结点插入链表头部
LinkNode node = new LinkNode();
node.value = element;
node.next = L.next;
L.next = node;
}
public static void print(LinkNode Link) { // 打印链表
LinkNode p = Link;
String str = "";
while(p != null){
str += p.value;
p = p.next;
}
System.out.println(str);
}
}