LRU设计
1 //leetcode 146.LRU缓存 2 #include <iostream> 3 #include <unordered_map> 4 using namespace std; 5 struct DlinkedNode{ 6 int key,value; 7 DlinkedNode* pre; 8 DlinkedNode* next; 9 DlinkedNode():key(0),value(0),pre(nullptr),next(nullptr){} 10 DlinkedNode(int _key,int _value):key(_key),value(_value),pre(nullptr),next(nullptr){} 11 }; 12 class LRUCache{ 13 private: 14 unordered_map<int,DlinkedNode*> cache; 15 DlinkedNode* head=new DlinkNode();//虚拟头 16 DlinkedNode* tail=new DlinkNode();//虚拟尾 17 int size; 18 int capacity; 19 public: 20 //LRUCache():default; 21 LRUCache(int _capacity):capacity(_capacity),size(0){
24 head->next = tail; 25 tail->pre = head; 26 } 27 int get(int key){ 28 if(!cache.count(key))//key不存在 29 { 30 return -1; 31 } 32 //如果key存在,先通过哈希表定位,再移到头部 33 /*DlinkedNode* node = cache[key]; 34 moveToHead(node); 35 return node->value; */ 36 moveToHead(cache[key]); 37 return cache[key]->value; 38 } 39 void put(int key,int value){ 40 if (!cache.count(key)) {//元素不存在 41 DlinkedNode* node= new DlinkedNode(key,value);//创建一个新节点 42 cache[key] = node;//插入哈希表 43 addToHead(node);//添加到双链表头部 44 ++size;//当前哈希表中元素个数 45 if (size > capacity) 46 { 47 //超出容量,删除双向链表尾部节点 48 DlinkedNode* removed = removeTail(); 49 //删除哈希表中对应的项 50 cache.erase(removed->key); 51 //防止内存泄漏 52 delete removed; 53 --size; 54 } 55 } 56 else{//如果哈希表中存在key,更新value,再把它移到头部 57 DlinkedNode* node = cache[key]; 58 node->value=value; 59 moveToHead(node); 60 } 61 } 62 void addToHead(DlinkedNode* node){ 63 node->pre = head;//虚拟头节点 64 node->next = head->next; 65 head->next->pre= node; 66 head->next = node; 67 } 68 void removeNode(DlinkedNode* node)//断开某个节点 69 { 70 node->pre->next = node->next; 71 node->next->pre = node->pre; 72 } 73 void moveToHead(DlinkedNode* node)//移动某个节点到头部 74 { 75 removeNode(node); 76 addToHead(node); 77 } 78 DlinkedNode* removeTail(){//删除最久未使用的节点 79 DlinkedNode* node = tail->pre;//实际上是最后一个节点 80 removeNode(node); 81 return node; 82 83 } 84 void lru_print() 85 { 86 unordered_map<int,DlinkedNode*>::iterator it=cache.begin(); 87 while(it!=cache.end()) 88 { 89 cout<<"key: "<<it->first<<" value: "<<it->second->value<<" "<<endl; 90 ++it; 91 } 92 /*for(const auto it:cache)//基于范围for循环 93 { 94 cout<<it.first<<" "<<(it.second)->value<<" "<<endl; 95 }*/ 96 } 97 }; 98 int main(int argc, char *argv[]) 99 { 100 LRUCache lruCache(2);//容量设为2 101 lruCache.put(1,1); 102 lruCache.put(2,2); 103 lruCache.get(1); 104 lruCache.put(3,3); 105 lruCache.get(2); 106 lruCache.put(4,4); 107 lruCache.get(1); 108 lruCache.get(3); 109 lruCache.get(4); 110 lruCache.lru_print(); 111 return 0; 112 }