单链表之lru算法实现

什么是lru算法

内存淘汰机制:

  • FIFO(First in,First out):队列,也就是先进先出的数据结构
  • LFU(Least Frequently Used):访问最常用的
  • LRU(Least Recently Used):访问最近访问过的,热点命中

单链表实现

实现一个单链表,包括增删查改的方法。

/**
 * @Auther: allen
 * @Date: 2019/8/22 14:40
 * @Description: 单链表
 */
public class LinkedList {

    /**
     * 头节点
     */
    protected Node head;

    /**
     * 集合大小
     */
    protected int size;

 public LinkedList() {
        this.size = 0;
    }


    class Node{
        T data;

        Node next;

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

    //增加

    /**
     * 向链表头部添加元素
     * @param data
     */
    protected void put(T data){
        Node node = head;

        Node curNode = new Node(data, head);

        head = curNode;

        size ++;
    }

    /**
     * 向链表指定下标添加元素
     * @param index
     * @param data
     */
    protected void put(int index, T data){
        checkPointIndex(index);

        //如果index等于0,直接调用put方法
        if ( index == 0 ){
            put(data);
            return;
        }

        Node previous = head;
        Node cur = head;

        for (int i = 0; i < index; i++) {
            previous = cur;
            cur = cur.next;
        }

        Node node = new Node( data, cur);
        previous.next = node;

        size++;
    }

    /**
     * 检查下标是否越界
     * @param index
     */
    protected void checkPointIndex(int index) {
        if( !( index >= 0 && index <= size )) {
            throw new IndexOutOfBoundsException("index:" + index + ", size:" + size);
        }
    }

    //删除

    /**
     * 移除链表头部元素
     * @return
     */
    protected T remove(){
        if( head != null ){
            Node node = head;
            head = node.next;

            node.next = null; //help gc
            size--;
            return node.data;
        }

        return  null;
    }

    /**
     * 移除链表指定下标元素
     * @param index
     * @return
     */
    protected T remove(int index){

        checkPointIndex(index);


        Node pervious = head;
        Node cur = head;
        for (int i = 0; i < index; i++) {
            pervious = cur;
            cur = cur.next;
        }

        pervious.next = cur.next;
        cur.next = null; //help gc

        size--;
        return cur.data;
    }

    /**
     * 移除链表最后一个元素
     * @return
     */
    protected T removeLast(){
        if( head != null ){
            Node pervious = head;
            Node cur = head;

            while ( cur.next != null ){
                pervious = cur;
                cur = cur.next;
            }

            cur.next = null;
            size --;
            return cur.data;
        }

        return null;
    }

    //修改

    /**
     * 修改链表指定下标元素
     * @param index
     * @param data
     */
    protected void set(int index, T data) throws Exception {
        checkPointIndex(index);

        if( head == null ){
            throw new Exception("链表为空,不能修改");
        }

        Node cur = head;
        for (int i = 0; i < index; i++) {
            cur = cur.next;
        }
        cur.data = data;
    }

    //查询

    /**
     * 获取链表头部元素
     * @return
     */
    protected T get(){
        if( head != null ){
            return head.data;
        }else {
            return null;
        }

    }

    /**
     * 获取链表指定下标元素
     * @param index
     * @return
     */
    protected  T get(int index) throws Exception {
        checkPointIndex(index);

        if( head == null ){
            throw new Exception("链表为空,获取元素失败");
        }

        Node cur = head;
        for (int i = 0; i < index; i++) {
            cur = cur.next;
        }

        return cur.data;
    }

 @Override
    public String toString() {
        Node cur = head;

        for (int i = 0; i < size; i++) {
            System.out.print(cur.data + " ");
            cur = cur.next;
        }
        System.out.println();
        return super.toString();
    }

 public static void main(String[] args) throws Exception{
        LinkedList list = new LinkedList();
        for (int i = 0; i < 5; i++) {
            list.put(i);
        }

        list.toString();

        //list.set(0,19);
        //
        //list.toString();

        list.put(0,11);

        list.toString();
        //try {
        //    list.set(0,4);
        //} catch (Exception e) {
        //    e.printStackTrace();
        //}


    }
}

基于单链表实现lru算法

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

继承单链表,实现例如lru算法。

/**
 * @Auther: allen
 * @Date: 2019/8/22 17:38
 * @Description: 用单链表实现lru缓存算法
 */
public class LruLinkedList extends LinkedList {

    /**
     * 内存限制大小
     */
    private int memory_size;

    /**
     * 默认的内存限制大小
     */
    private static int DEFAULT_CAPACITY = 5;

    /**
     * @param data
     */
    public void lruPut(T data){
        //1.新数据插入到链表头部
        //2.当链表满的时候,将链表尾部的数据丢弃
        if( size >= memory_size ){
            removeLast();
            put(data);
        }else {
            put(data);
        }
    }

    /**
     *
     * @return
     */
    public T lruRemove(){
        return removeLast();
    }

    /**
     * lruGet方法
     * @return
     */
    public T lruGet(int index){
        //当缓存命中(即缓存数据被访问),数据要移到表头
        checkPointIndex(index);

        //当集合为空时,读取抛出异常,或者直接返回null
        if( head == null ){
            return null;
        }

        Node pervious = head;
        Node cur = head;
        for (int i = 0; i < index; i++) {
            pervious = cur;
            cur = cur.next;
        }

        //保存返回结果
        T result = cur.data;

        //把当前节点移到头节点

        //移除当前节点
        pervious.next = cur.next;

        //把当前节点移到表头
        cur.next = head;

        //保存头节点信息
        head = cur;


        return result;
    }

    public static void main(String[] args) {
        LruLinkedList lruList = new LruLinkedList();

        for (int i = 0; i < 5; i++) {
            lruList.lruPut(i);
        }

        lruList.toString();

        lruList.lruGet(3);

        lruList.toString();


    }

    public LruLinkedList() {
        this(DEFAULT_CAPACITY);
    }

    public LruLinkedList(int memory_size) {
        this.memory_size = memory_size;
    }
}

你可能感兴趣的:(java)