數據結構與算法系列—數組實現LRU(最近最少使用)緩存算法


本文使用數組實現最近最少使用緩存算法。

算法思想:

1、訪問某元素時,先判斷緩存中是否存在該元素。

2、如果存在,將該元素前面的元素向右移動一位,將該元素移動到數組首位。

3、如果不存在

1)數組已滿時,刪除末端元素,將所有元素向右移動一位,將新元素插到首位。

2)數組未滿時,將所有元素向后移動一位,將新元素插入到數組首位。

代碼實現

package com.datastructure.array;

import java.util.HashMap;
import java.util.Map;

/**
 * 基於數組實現的LRU緩存
 * 1. 空間復雜度為O(n)
 * 2. 時間復雜度為O(n)
 * 3. 不支持null的緩存
 *
 * @Auther: dlm
 * @Date: 2020/4/6 17:31
 */
public class LRUBasedArray<T> {
    //默認容量  2的3次方
    private static final int DEFALUT_CAPACITY = (1 << 3);
    //用戶自定義容量
    private int capacity;
    //現有元素個數
    private int count;
    //存儲元素的數組
    private T[] value;
    //存儲元素及其位置的對應關系
    private Map<T,Integer> holder;

    public LRUBasedArray(int capacity){
        this.capacity = capacity;
        this.count = 0;
        this.value = (T[])new Object[capacity];
        holder = new HashMap<>(capacity);
    }

    public LRUBasedArray(){
        this(DEFALUT_CAPACITY);
    }

    //訪問某元素
    public void offer(T value){

        if(value == null){
            throw new IllegalArgumentException("暫不支持null!");
        }

        Integer index = holder.get(value);
        if(index == null){  //緩存中不存在該元素
            if(isFull()){   //緩存已滿
                removeAndCache(value);
            }else{  //緩存未滿
                cache(value,count);
            }

        }else { //緩存存在該元素
            update(value,index);
        }
    }

    private void removeAndCache(T e) {
        T last = value[--count];
        holder.remove(last);
        cache(e,count);
    }

    private void update(T e, Integer index) {
        rightShift(index);
        value[0] = e;
        holder.put(e,0);
    }

    private void cache(T e,int end) {
        rightShift(end);
        value[0] = e;
        holder.put(e,0);
        count++;
    }

    //將count之前的元素都向右移動
    private void rightShift(int end) {
        for(int i = end - 1;i >= 0 ;i--){
            value[i+1] = value[i];
            holder.put(value[i],i + 1);
        }
    }

    private boolean isFull() {
        return count == capacity;
    }

    @Override
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder();
        for(int i = 0;i < count;i++){
            stringBuilder.append(value[i]);
            stringBuilder.append(" ");
        }
        return stringBuilder.toString();
    }

    static class TestLRUBasedArray{
        public static void main(String[] args) {
            testDefalutCapacity();
            //testSpecificCapacity(4);
            //testException();
        }

        public static void testDefalutCapacity(){
            System.out.println("======無參測試========");
            LRUBasedArray<Integer> lru = new LRUBasedArray<Integer>();
            lru.offer(1);
            lru.offer(2);
            lru.offer(3);
            lru.offer(4);
            lru.offer(5);
            System.out.println(lru);
            lru.offer(6);
            lru.offer(7);
            lru.offer(8);
            lru.offer(9);
            System.out.println(lru);
        }

        public static void testSpecificCapacity(int capacity){
            System.out.println("======有參測試========");
            LRUBasedArray<Integer> lru = new LRUBasedArray<Integer>(capacity);
            lru.offer(1);
            System.out.println(lru);
            lru.offer(2);
            System.out.println(lru);
            lru.offer(3);
            System.out.println(lru);
            lru.offer(4);
            System.out.println(lru);
            lru.offer(2);
            System.out.println(lru);
            lru.offer(4);
            System.out.println(lru);
            lru.offer(7);
            System.out.println(lru);
            lru.offer(1);
            System.out.println(lru);
            lru.offer(2);
            System.out.println(lru);
        }

        public static void testException(){
            LRUBasedArray<Integer> lru = new LRUBasedArray<Integer>();
            lru.offer(null);
        }

    }

}
歡迎關注個人公眾號,可直接掃描以下二維碼或微信搜索“阿毛聊技術”。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM