双向链表实现Lru算法

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("");
        }
    }
}
    原文作者:mannnn__
    原文地址: https://blog.csdn.net/mannnn__/article/details/83892278
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞