Android中的数据结构和算法-实现自己的LRU算法

文章目录

  • 1 内存缓存淘汰机制
  • 2 实现自己的单链表
  • 3 基于单链表手写实现LRU算法

1 内存缓存淘汰机制

  • LRU (Least recently used) 最近最少使用,如果数据最近被访问过,那么将来被访问的几率也更高。

  • LFU (Least frequently used) 最不经常使用,如果一个数据在最近一段时间内使用次数很少,那么在将来一段时间内被使用的可能性也很小。

  • FIFO (Fist in first out) 先进先出, 如果一个数据最先进入缓存中,则应该最早淘汰掉。

LRU算法示意图:
Android中的数据结构和算法-实现自己的LRU算法_第1张图片

  1. 新数据插入到链表头部
  2. 当缓存命中(即缓存数据被访问),数据要移到表头
  3. 当链表满的时候,将链表尾部的数据丢弃

2 实现自己的单链表

package test;

//单链表
public class LinkedList<T> {

    Node list;
    int size; //链表有多少个节点

    public LinkedList() {
        size = 0;
    }

    //添加节点
    //在头部添加节点
    public void put(T data) {
        Node head = list;
        Node curNode = new Node(data, list);
        list = curNode;
        size++;
    }

    //在链表的index 位置插入一个新的数据data
    public void put(int index, T data) {
        checkPositionIndex(index);
        Node cur = list;
        Node head = list;
        for (int i = 0; i < index; i++) {
            head = cur;
            cur = cur.next;
        }
        Node node = new Node(data, cur);
        head.next = node;
        size++;

    }

    //删除节点
    //删除头部节点
    public T remove() {
        if (list != null) {
            Node node = list;
            list = list.next;
            node.next = null; // GC 回收
            size--;
            return node.data;
        }
        return null;
    }

    public T remove(int index) {
        checkPositionIndex(index);
        Node head = list;
        Node cur = list;
        for (int i = 0; i < index; i++) {
            head = cur;
            cur = cur.next;
        }
        head.next = cur.next;
        cur.next = null;//GC
        return cur.data;
    }

    public T removeLast() {
        if (list != null) {
            Node node = list;
            Node cur = list;
            while (cur.next != null) {
                node = cur;
                cur = cur.next;
            }
            node.next = null;
            size--;
            return cur.data;

        }
        return null;
    }

    //修改节点
    public void set(int index, T newData) {
        checkPositionIndex(index);
        Node head = list;
        for (int i = 0; i < index; i++) {
            head = head.next;
        }
        head.data = newData;
    }

    //查询节点
    //get 头部节点
    public T get() {
        Node node = list;
        if (node != null) {
            return node.data;
        } else {
            return null;
        }
    }

    public T get(int index) {
        checkPositionIndex(index);
        Node node = list;
        for (int i = 0; i < index; i++) {
            node = node.next;
        }
        return node.data;
    }

    //检测index是否在链表范围以内
    public void checkPositionIndex(int index) {
        if (!(index >= 0 && index <= size)) {
            throw new IndexOutOfBoundsException("index: " + index + ", size: " + size);
        }

    }

    @Override
    public String toString() {
        Node node = list;
        for (int i = 0; i < size; i++) {
            System.out.print(node.data + " ");
//			System.out.print(" ");
            node = node.next;
        }
        System.out.println();
        return super.toString();
    }

    //节点的信息
    class Node {
        T data;
        Node next;

        public Node(T data, Node node) {
            this.data = data;
            this.next = node;
        }
    }


    public static void main(String[] args) {
        LinkedList<Integer> list = new LinkedList<>();
        for (int i = 0; i < 5; i++) {
            list.put(i);
        }
        list.toString();
        list.put(3, 3);
        list.toString();
        list.put(8);
        list.toString();
        System.out.println(list.get(2));
    }
}

Android中的数据结构和算法-实现自己的LRU算法_第2张图片


3 基于单链表手写实现LRU算法

package test;

public class LruLinkedList<T> extends LinkedList<T> {

    int memory_size; // 用于限定内存空间大小,也就是缓存的大小
    static final int DEFAULT_CAP = 5;

    public LruLinkedList() {
        this(DEFAULT_CAP);
    }

    public LruLinkedList(int default_memory_size) {
        memory_size = default_memory_size;
    }

    //LRU添加节点
    public void lruPut(T data) {
        if (size >= memory_size) {
            removeLast();
            put(data);
        } else {
            put(data);
        }
    }

    //LRU删除
    public T lruRemove() {
        return removeLast();
    }

    //LRU访问
    public T lruGet(int index) {
        checkPositionIndex(index);
        Node node = list;
        Node pre = list;
        for (int i = 0; i < index; i++) {
            pre = node;
            node = node.next;
        }
        T resultData = node.data;
        //将访问的节点移到表头
        pre.next = node.next;
        Node head = list;
        node.next = head;
        list = node;
        return resultData;
    }


    public static void main(String[] args) {
        LruLinkedList<Integer> lruLinkedList = new LruLinkedList<>(5);
        for (int i = 0; i < 4; i++) {
            lruLinkedList.lruPut(i);
        }
        lruLinkedList.toString();
        System.out.println(lruLinkedList.lruGet(3));
        lruLinkedList.toString();
        lruLinkedList.lruPut(20);
        lruLinkedList.toString();

        lruLinkedList.lruPut(18);
        lruLinkedList.toString();

    }

}

Android中的数据结构和算法-实现自己的LRU算法_第3张图片

你可能感兴趣的:(#,数据结构算法,LRU算法,LinkedList)