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 }