C#简单实现LRU缓存

  最近跟同学吃饭扯淡的时候,由技术扯到薪资,又由薪资扯到他找工作时跟面试官是怎么扯淡拿高工资的,各种技术一顿侃,总之只要啥都了解就没问题了。谈到缓存的时候,我试探性的问了问- -你还记得LRU怎么写吗,他说啥完?我说没事。。

 写完这篇文章发给他- -鄙视完他让他请我再吃饭,标准的缓存LRU实现为哈希表+链表,这是热乎的双向链表,也是C#版本的。。C#实现双向链表 

代码:

    public class LRUCache<T>
    {
        private int _size;//链表长度
        private int _capacity;//缓存容量 
        private Dictionary<int, ListNode<T>> _dic;//key +缓存数据
        private ListNode<T> _linkHead;
        public LRUCache(int capacity)
        {
            _linkHead = new ListNode<T>(-1, default(T));
            _linkHead.Next = _linkHead.Prev = _linkHead;
            this._size = 0;
            this._capacity = capacity;
            this._dic = new Dictionary<int, ListNode<T>>();
        }

        public T Get(int key)
        {
            if (_dic.ContainsKey(key))
            {
                ListNode<T> n = _dic[key];
                MoveToHead(n);
                return n.Value;
            } 
            else
            {
                return default(T);
            }
        }
        public void Set(int key, T value)
        {
            ListNode<T> n;
            if (_dic.ContainsKey(key))
            {
                n = _dic[key];
                n.Value = value;
                MoveToHead(n);
            }
            else
            {
                n = new ListNode<T>(key, value);
                AttachToHead(n);
                _size++;
            } 
            if (_size > _capacity)
            {
                RemoveLast();// 如果更新节点后超出容量,删除最后一个
                _size--;
            }
            _dic.Add(key, n);
        }
        // 移出链表最后一个节点
        private void RemoveLast()
        {
            ListNode<T> deNode = _linkHead.Prev;
            RemoveFromList(deNode);
            _dic.Remove(deNode.Key);
        }
        // 将一个孤立节点放到头部
        private void AttachToHead(ListNode<T> n)
        {
            n.Prev = _linkHead;
            n.Next = _linkHead.Next;
            _linkHead.Next.Prev = n;
            _linkHead.Next = n;
        }
        // 将一个链表中的节点放到头部
        private void MoveToHead(ListNode<T> n)
        {
            RemoveFromList(n);
            AttachToHead(n);
        }
        private void RemoveFromList(ListNode<T> n)
        {
            //将该节点从链表删除
            n.Prev.Next = n.Next;
            n.Next.Prev = n.Prev;
        }
    }

    public class ListNode<T>
    {
        public ListNode<T> Prev;
        public ListNode<T> Next;
        public T Value;
        public int Key;

        public ListNode(int key, T val)
        {
            Value = val;
            Key = key;
            this.Prev = null;
            this.Next = null;
        }
    }

测试:

          LRUCache<int> cache = new LRUCache<int>(3);
            cache.Get(1);
            cache.Set(1, 1);
            cache.Set(2, 2);
            cache.Get(3);
            cache.Set(3, 3); 
            cache.Set(4, 4);
            cache.Get(2);
原文地址:https://www.cnblogs.com/ylsforever/p/6511000.html