zoukankan      html  css  js  c++  java
  • 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);
  • 相关阅读:
    重新想象 Windows 8 Store Apps (32) 加密解密: 非对称算法, 数据转换的辅助类
    《C#编程极限》目录
    《软件设计精要与模式》完稿(原名《软件设计之道》)
    《软件设计之道》正式更名为《软件设计精要与模式》
    《软件设计精要与模式》各篇之篇首语
    Visual Studio 2005单元测试中关于外部文件的问题解决
    Web Service Software Factory
    Windows下IIS+PHP 5.2的安装与配置
    规划你的C#程序——《C#编程极限》第一章
    《软件设计精要与模式》前言
  • 原文地址:https://www.cnblogs.com/ylsforever/p/6511000.html
Copyright © 2011-2022 走看看