LRU算法实现 双向链表+哈希表

  1. 创建一个双向链表,有key ,value, 前驱节点 和后继节点
class Node{
        int key;
        int value;
        Node next;
        Node pre;
        Node(int key,int value){
            this.key=key;
            this.value=value;
        }
    }
  1. 在主类里面创建四个实例字段
    private int capacity;
    //通过hash表的方法以O(1)的时间复杂度找到结点,并对他进行相应的移动
    private HashMap<Integer, Node> map;
    //记录头部结点和尾部节点,方便移动
    private Node head;
    private Node tail;
  1. put方法的实现,从hashmap中直接取值,如果不为null,则将node的值更新,并把该节点利用moveNodeToTail方法移动到链表末尾,如果为null,则创建一个新的node结点,然后计算当前map的大小是否已经到达门槛值,需要移除队头元素,调用removeHead方法,进行移除,然后调用addLast方法,将新的node结点加入链表,并且加入hashmap中
public void put(int key, int value) {
        Node node=map.get(key);
        if(node!=null){
            node.value=value;
            moveNodeToTail(node);
            return;
        }
        Node tmp=new Node(key,value);
        if(map.size()==capacity){
            Node delHead = removeHead();
            map.remove(delHead.key);
        }
        addLast(tmp);
        map.put(key,tmp);
        
        return;
    }
  1. get方法实现,map.get(key)的值如果为null的话,就返回-1,如果不等于null,则将该节点利用moveNodeToTail方法移动到末尾,并且返回当前结点的值
    public int get(int key) {
        Node node=map.get(key);
        if(node!=null){
            moveNodeToTail(node);
            return node.value;
        }
        return -1;
    }
  1. 附加方法
    addLast方法:首先判断node是否为null,不为null的话,判断当前的头结点和尾结点是否为null,为null,就创建头尾指针,不为null,则通过尾部节点连接新的结点,
    moveNodeToTail方法:首先找出特殊情况,node为头部结点和尾部节点的情况
    为尾部节点就不需要更新,为头部结点的话,head=node.next;head.pre=null;
    removeHead方法:判断head是否为null,然后判断head==tail,重新定义,
    否则利用链表的移除法则移除就行了
public void addLast(Node node){
        if(node==null)return;
        if(head==null){
            //创建头尾指针
            head=node;
            tail=node;
        }else{
            //连接新节点
            tail.next=node;
            node.pre=tail;
            //更新尾结点为新节点
            tail=node;
        }
    }
     public Node removeHead() {
         if(head==null){
             return null;
         }
         Node res=head;
         if(head==tail){
             head=null;
             tail=null;
         }else{
             head=head.next;
             head.pre=null;
             res.next=null;
         }
         return res;
     }
    public void moveNodeToTail(Node node){
        if(tail==node)return;
        if(head==node){
            head=node.next;
            head.pre=null;
        }else{
            node.pre.next=node.next;
            node.next.pre=node.pre;
        }
        node.pre=tail;
        node.next=null;
        tail.next=node;
        tail=node;
    }
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值