来源1:http://blog.csdn.net/tinyway/article/details/24536327html
来源2:https://www.cnblogs.com/mushroom/p/4278275.html#o1node
来源3:双向列表的插入顺序: https://www.cnblogs.com/Renyi-Fan/p/7512789.html数组
LRU便是:把最近最少访问的数据给淘汰掉,常常被访问到便是热点数据。数据结构
关于LRU数据结构:由于key优先级提高和key淘汰,因此须要顺序结构。函数
新数据插入到链表头部、被命中时的数据移动到头部,添加复杂度O(1),移动和获取复杂度O(N)。spa
LRU的实现有这样几种思路:.net
一、利用数组保存节点信息,另外节点信息除了内容还须要保存最近使用状况。code
缺点:每次都须要遍从来找信息,同时也要遍从来删除(指LRU cache满了的状况)htm
二、链表来保存节点,双向链表,最末端为最新使用的,这样能减小删除时候的时间效率。blog
三、还能够用一个哈希表来储存key值对应的节点的地址,这样就能够实现查找O(1),删除添加O(1)了
//用双向链表来做为LRU的结构 //其中表头表示早入表的节点,表尾表示最新的节点 struct ListNode{ string key; string value; ListNode* next; ListNode* pre; //struct的构造函数 ListNode(string k,string v):key(k),value(v),next(NULL),pre(NULL){} }; class LRUCache{ private: int cap; int nodeNum; ListNode pHead; ListNode PTail; public: LRUCache(int capacity):cap(capacity),nodeNum(0),pHead(NULL),pTail(NULL){} string get(string key){ if(pHead==NULL) return ''; ListNode *pNode = pHead; while(pNode != NULL){ if(pNode->key == key){ string val = pNode->value; DeleteFromList(pNode); AddToList(pNode); return val } pNode = pNode->next; } //key is not found return '' } void set(string key, string val){ ListNode pNode = pHead; //要考虑为已有的key从新赋值 while(pNode!=NULL){ if(pNode->key==key){ pNode->value = val; DeleteFromList(pNode); AddToList(pNode); return; } pNode = pNode->next; } //为一个新的key存值 pNode = new ListNode(key,val); AddToList(pNode); } //删除pNode void DeleteFromList(ListNode* pNode){ ListNode* pPre = pNode->pre; ListNode* pNext = pNode->next; nodeNum--; //将pPre的next指向pNext即删除,但要考虑pNode是链表头的状况 if(pPre==NULL) pHead=pNext; else pPre->next = pNext; //将pNext的pre指向pPre即删除,但要考虑pNode是链表尾的状况 if(pNext==NULL) pTail = pPre; else pNext->pre = pPre; } //将pNode添加到链表 void AddToList(ListNode* pNode){ if(nodeNum == cap){ ListNode* pTmp = pHead; pHead = pHead->next; DeleteFromList(pTmp); delete pTmp; AddToList(pNode); } else{ ++nodeNum; if(nodeNum == 1){ pHead = pNode; pTail = PNode; } else{ //对于尾端加链表,不单单是链表插入顺序,还要更新pTail pNode->pre = pTail; pNode->next = pTail->next; pTail->next = pNode; pTail = pNode; } } } } //双向链表维护:pHead,pTail,numNode这三个成员,平时的操做要注意numNode //边界状况必定要注意维护pHead和pTail。
基于map或是dict的待完成。