146. LRU缓存机制

 1 //双向链表(同时存储key和val)+hash表
 2 //很容易犯错的一点是:处理链表节点的同时不要忘了更新哈希表中对节点的映射。
 3 class LRUCache 
 4 {
 5     int n;//大小
 6     list<pair<int,int>> li;//链表
 7     unordered_map<int,list<pair<int,int>>::iterator> hash;//(key,对应链表迭代器)
 8 public:
 9     LRUCache(int capacity) 
10     {
11         n = capacity;//初始化
12     }
13     
14     int get(int key) 
15     {
16         if(hash.find(key) != hash.end())//如果找到了
17         {
18             pair<int,int> temp = *hash[key];//备份pair
19 
20             li.erase(hash[key]);//从链表中删除key对应的迭代器
21             li.push_front(temp);//在链表头部添加备份的pair
22 
23             hash.erase(key);//在hash中删除
24             hash[key] = li.begin();//key对应链表首部
25             return temp.second;
26         }
27         else return -1;
28     }
29     
30     void put(int key, int value) 
31     {
32         if(hash.find(key) != hash.end())
33         {
34             li.erase(hash[key]);//从链表中删除key对应的迭代器
35             li.push_front({key,value});//在链表头部添加(key,value)
36             
37             hash.erase(key);//在hash中删除
38             hash[key] = li.begin();//key对应链表首部
39         }
40         else
41         {
42             if(n == hash.size())//如果大小已满
43             {
44                 auto it = li.back();//找到链表尾部
45 
46                 li.pop_back();//删除链表尾部
47                 hash.erase(it.first);//在hash中删除
48             //这里就能回答之前的问答题“为什么要在链表中同时存储 key 和 val,而不是只存储 val”
49             }
50             li.push_front({key,value});//在链表头部添加(key,value)
51             hash[key] = li.begin();//key对应链表首部
52         }
53     }
54 };

 

posted @ 2020-04-02 22:27  Jinxiaobo0509  阅读(149)  评论(0)    收藏  举报