Lru算法实现:节点依次在链表头部插入,链表尾部即为最近最少使用的节点,当key重复时,新增节点覆盖原有节点,查找时,将查找到的节点放到链表头部。
/**
* @author spark
* @version 1.0
*/
public class MyLRU {
/**
* 定义双向链表
*/
static class LinkedNode {
String key;
Object val;
LinkedNode preNode;
LinkedNode postNode;
public LinkedNode(String key, Object val) {
this.key = key;
this.val = val;
}
}
/**
* Lru实现
*/
static class Lru {
int size;
//存储容量,默认存3个
int capacity = 3;
//用作标记
LinkedNode head = new LinkedNode(new String("head"), new Object());
LinkedNode tail;
public Lru(int capacity) {
this.capacity = capacity;
}
/**
* 插入
*/
public void insert(String key, Object val) {
LinkedNode newNode = new LinkedNode(key, val);
LinkedNode selectNode = selectNode(key);
//容量满时
if (size + 1 > capacity) {
//有重复的key,移除久的节点
if (selectNode != null) {
removeNode(selectNode);
} else {
//删除最后一个节点
tail = tail.preNode;
tail.postNode = null;
}
// 插入到首位
newNode.postNode = head.postNode;
newNode.preNode = head;
head.postNode = newNode;
} else {
// 第一次插入
if (head.postNode == null) {
head.postNode = newNode;
newNode.preNode = head;
tail = newNode;
} else {
removeNode(selectNode);
//头插
newNode.postNode = head.postNode;
newNode.preNode = head;
head.postNode = newNode;
newNode.postNode.preNode = newNode;
}
size++;
}
}
//移除指定节点
public void removeNode(LinkedNode selectNode) {
//未插满
if (selectNode != null) {
//移除查到的节点
selectNode.postNode.preNode = selectNode.preNode;
selectNode.preNode.postNode = selectNode.postNode;
//如果是尾节点
if (selectNode.key.equals(tail.key)) {
tail = tail.preNode;
}
}
}
//查找key所在的节点
public LinkedNode selectNode(String key) {
LinkedNode dumpNode = head.postNode;
while (dumpNode != null) {
if (dumpNode.key.equals(key)) {
return dumpNode;
}
dumpNode = dumpNode.postNode;
}
return null;
}
/**
* 查询
*/
public Object select(String key) {
LinkedNode dumpNode = selectNode(key);
if (dumpNode == null) {
return null;
} else {
//将查询到的节点移动到链表前面
dumpNode.postNode.preNode = dumpNode.preNode;
dumpNode.preNode.postNode = dumpNode.postNode;
dumpNode.preNode = head;
dumpNode.postNode = head.postNode;
dumpNode.postNode.preNode = dumpNode;
head.postNode = dumpNode;
//如果是最后一个节点
if (tail.key.equals(key)) {
tail = tail.preNode;
tail.postNode = null;
}
}
return dumpNode.val;
}
public static void main(String[] args) {
Lru lru = new Lru(3);
lru.insert("a", 1);
lru.insert("b", 2);
lru.insert("c", 3);
lru.insert("c", 4);
System.out.println("");
}
}
}