手写lru,要求get、put都是O(1)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


前言

此文章用于自己学习记录。
面试官:对LRU算法了解过吗?实现LRU,要求get、和put操作都是O(1)。
实现O(1)操作可以用Map和双向链表两种集合可以轻松实现LRU。


直接上代码


/**
 * 手写LRU,使得get和put都是O(0)
 */
public class LruDemo {
	//默认存储最大值
    private int MAXSIZE = 10;
    //当前存储数据个数
    private int size = 0;
    private Map<String, Link> map = new HashMap<>();
    //头部,不存数据,用来定位
    private Link head = new Link();
    //尾部
    private Link wei = new Link();

    public LruDemo(int max) {
        this.MAXSIZE = max;
        //实例化必须将头尾相连
        head.next = wei;
        wei.prv = head;
    }

    public String get(String key) {
        if (map.containsKey(key)) {
            Link link = map.get(key);
            //使目标link的上一个link 和 下一个link 相连
            link.prv.next = link.next;
            link.next.prv = link.prv;
            //将link移动到第一位
            link.next = head.next;
            head.next.prv = link;
            link.prv = head;
            head.next = link;
            return map.get(key).value;
        }
        return null;
    }

    public void put(String key, String value) {
        if (map.containsKey(key)) {
            Link linkIndex = map.get(key);
            linkIndex.value = value;
            map.put(key, linkIndex);
            //TODO 移动到链表头部
            linkIndex.prv.next = linkIndex.next;
            linkIndex.next.prv = linkIndex.prv;
            head.next.prv = linkIndex;
            linkIndex.next = head.next;
            head.next = linkIndex;
            linkIndex.prv = head;
            return;
        }
        if (size >= MAXSIZE) {
            //TODO 删除尾节点
            Link link1 = wei.prv.prv;
            Link link2 = wei.prv;
            link1.next = wei;
            link2.prv = null;
            link2.next = null;
            wei.prv = link1;
            size--;
        }
        Link link = new Link(key, value);
        map.put(key, link);
        head.next.prv = link;
        link.next = head.next;
        link.prv = head;
        head.next = link;
        size++;
    }

	/**
	 * 用于测试:正序打印
	 */
    public void printLruDemoASC() {
        Link index = head.next;
        int i = 1;
        while (index != null && index != wei) {
            System.out.println("第" + i + "个: key = " + index.key + "   value = " + index.value);
            index = index.next;
            i++;
        }
    }

	/**
	 * 用于测试:倒打印
	 */
    public void printLruDemoDESC() {
        Link index = wei.prv;
        int i = size;
        while (index != null && index != head) {
            System.out.println("第" + i + "个: key = " + index.key + "   value = " + index.value);
            index = index.prv;
            i--;
        }
    }

    public int size() {
        return this.size;
    }



    class Link {
        String value;
        String key;
        Link prv;
        Link next;

        public Link(String key, String value) {
            this.key = key;
            this.value = value;
        }

        public Link() {

        }
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值