資料結構系列之單連結串列實現一個簡單的LRU演算法

深夜程猿發表於2019-04-03

更多文章,歡迎關注微信公眾號:深夜程猿

資料結構系列之單連結串列實現一個簡單的LRU演算法

在上一篇文章簡單聊聊了LRU演算法理論篇,這裡就和大家使用單連結串列實現一個簡單的LRU演算法。其它型別的實現一樣的思路,只不過是處理的複雜程度不一樣而已。

Node.java:儲存資料的結點

package lru;

/**
 * @author wu
 * @since 2019/4/2
 */
public class Node<K, V> {

    private V data;

    private K key;
    /**
     * 指標,指向下一節點
     */
    private Node<K, V> next;


    public V getData() {
        return data;
    }

    public void setData(V data) {
        this.data = data;
    }

    public Node<K, V> getNext() {
        return next;
    }

    public void setNext(Node<K, V> next) {
        this.next = next;
    }

    public K getKey() {
        return key;
    }

    public void setKey(K key) {
        this.key = key;
    }
}

複製程式碼

LinkedLru.java:LRU實現

package lru;

/**
 * @author wu
 * @since 2019/4/2
 */
public class LinkedLru<K, V> {

    private Node<K, V> root;
    private int maxCapacity;
    private int defaultCapacity = 10;

    public LinkedLru(int maxCapacity) {
        if (maxCapacity <= 0) {
            throw new IllegalArgumentException("maxCapacity should not less than 0");
        }
        this.maxCapacity = maxCapacity;
    }

    public int getMaxCapacity() {
        return maxCapacity;
    }

    public LinkedLru() {
        this.maxCapacity = defaultCapacity;
    }

    public Node<K, V> get(K key) {

        if (key == null) {
            throw new IllegalArgumentException("key should not be null");
        }

        if (root == null) {
            return null;
        }

        Node<K, V> temp = root;
        while (temp != null) {
            if (key.equals(temp.getKey())) {
                Node<K, V> node = new Node<>();
                node.setData(temp.getData());
                node.setKey(temp.getKey());
                return node;
            }

            temp = temp.getNext();
        }

        return null;
    }

    public boolean add(Node<K, V> data) {

        if (data == null) {
            throw new IllegalArgumentException("can not cache null");
        }

        if (root == null) {
            root = data;
            return true;
        } else {
            Node<K, V> prev = root;
            Node<K, V> next = root.getNext();
            Node<K, V> header = root;
            Node<K, V> cursor;
            int index = 1;
            while (true) {
                index++;
                cursor = prev;
                if (index >= getMaxCapacity()) {
                    // 設定data為頭部結點
                    data.setNext(header);
                    root = data;
                    // 快取達到最大值,淘汰資料,此時prev就是尾部結點
                    cursor.setNext(null);
                    break;
                }

                if (next == null) {
                    // 容量沒有達到最大,已到快取尾部,並且資料還沒有快取過
                    data.setNext(header);
                    root = data;
                    cursor.setNext(null);
                    break;
                }

                if (next.getKey() == data.getKey()) {
                    // 資料存在,交換指標,資料放在首部
                    data.setNext(header);
                    prev.setNext(next.getNext());
                    root = data;
                    break;
                }

                prev = next;
                next = next.getNext();

            }


        }
        return true;
    }


    public Node<K, V> getRoot() {
        return root;
    }
}

複製程式碼

測試類:

package lru;

import com.alibaba.fastjson.JSON;

/**
 * @author wu
 * @since 2019/4/3
 */
public class Test {

    public static void main(String[] args) {

        LinkedLru<String, String> cache = new LinkedLru<>(10);
        int pos = 0;
        while (pos < 100) {
            pos++;
            Node<String, String> node = new Node();
            node.setKey("key:" + pos);
            node.setData("data:" + pos);
            cache.add(node);
        }
        System.out.println(JSON.toJSONString(cache.getRoot()));
        System.out.println(JSON.toJSONString(cache.get("key:10")));
        System.out.println(JSON.toJSONString(cache.get("key:100")));
    }

}

複製程式碼

輸出:

{"data":"data:100","key":"key:100","next":{"data":"data:99","key":"key:99","next":{"data":"data:98","key":"key:98","next":{"data":"data:97","key":"key:97","next":{"data":"data:96","key":"key:96","next":{"data":"data:95","key":"key:95","next":{"data":"data:94","key":"key:94","next":{"data":"data:93","key":"key:93","next":{"data":"data:92","key":"key:92","next":{"data":"data:91","key":"key:91"}}}}}}}}}}
null
{"data":"data:100","key":"key:100"}

複製程式碼

系列文章

資料結構小白系列之資料結構概述

資料結構系列之LRU演算法理論篇

相關文章