LRU算法最近最少使用 ----- Java实现

LRU算法常用于页面置换算法,是为虚拟页式存储管理服务的。他的设计思路是最近使用过的,就认为在将来有很大概率会使用。
现在认定缓存中的数据是key,value形式, 一种实现方式是使用链表,用链表存储key,value,把最近使用到的节点转移到头节点。分析时间复杂度:查找 o(n) , 插入o(1), 删除 o(n)。

这里使用了map进行优化,在缓存中的结点,都保存一组key,TreeNode到map,这样查询的时间变成o(1)。

还有一个是删除结点的优化,理论上删除链表只能是o(n),但是一种思路是这样的:假设要删除的结点后面存在结点, 那么把下一个结点的值拷贝到当前结点, 之后指针改到后一位去。 这样把删除优化到了o(1)。

下面是代码,有错误劳烦指出
package linkedNode;


import java.util.HashMap;
import java.util.Map;

class LinkedNode{
    public LinkedNode(int key,int val) {
        this.key = key;
        this.val = val;
        next = null;
    }
    int key;
    int val;
    LinkedNode next;
}
public class LRULinkedAndMap {

    private int size;
    private int count;
    private LinkedNode cacheList;
    private Map<Integer,LinkedNode> mp;

    // 构造方法
    public LRULinkedAndMap(int size) {
        this.size = size;
        this.cacheList = null;
        this.mp = new HashMap<>();
    }

    //set
    public void set(int key, int value) {
        if (cacheList == null) {
            LinkedNode node = new LinkedNode(key, value);
            mp.put(key, node);
            cacheList = node;
            return;
        }
        if (mp.containsKey(key)) {
            LinkedNode node = mp.get(key);
            deleteNodeO1(node);
            node.next = cacheList;
            cacheList = node;
        }else{
            LinkedNode node = new LinkedNode(key,value);
            mp.put(key, node);
            node.next = cacheList;
            cacheList = node;
            count ++;
            if (count == size) {
                //超出界限
                deleteLast();
            }
        }
    }

    private void deleteLast() {
        LinkedNode node = cacheList;
        if(count == 1) cacheList = null;
        while (node.next.next != null) {
            node = node.next;
        }
        mp.remove(node.next.key);
        node.next = null;
        count--;
    }

    // get
    // 如果在map中,就返回,并且将节点提到第一个位置
    // 如果不在,返回-1
    public int get(int key) {
        if (mp.containsKey(key)) {
            LinkedNode node = mp.get(key);
            deleteNodeO1(node);
            node.next = cacheList;
            cacheList = node;
            return node.val;
        }else{
            return -1;
        }
    }
    // 删除节点 o(n)
    void deleteNode(LinkedNode node) {

        LinkedNode pre = cacheList;
        if(node == cacheList){
            //要删除的点是头节点
            cacheList = pre.next;
            return;
        }
        while (pre.next != node) {
            pre = pre.next;
        }
        pre.next = node.next;
    }

    void deleteNodeO1(LinkedNode node) {
        if (node.next != null) {
            node.key = node.next.key;
            node.val = node.next.val;
            node.next = node.next.next;
        }else{
            // 如果是最后一个那么只能从头去删了
            deleteNode(node);
        }
    }
    private void printCache() {
        LinkedNode node = cacheList;
        System.out.println("cache:");
        while (node != null) {
            System.out.print(" -> " + node.val);
            node = node.next;
        }
        System.out.println();
    }
    public static void main(String[] args) {
        LRULinkedAndMap lru = new LRULinkedAndMap(3);
        System.out.println(lru.get(0));
        lru.set(1,100);
        lru.set(2,300);
        lru.set(4,500);
        lru.printCache();
        lru.set(1,100);
        lru.printCache();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值