题目描述:设计一个数据结构用来实现最近最少使用的缓存,它支持get 和set方法:
get(key) -- 如果key在缓存中,返回key所对应的value值(通常为正数),否则返回-1;
set(key,value) -- 如果key不在缓存中,将其插入缓存,如果缓存已经到达容量上限,则将最近最少使用的项退出缓存,再将其插入。
分析:我们可以采用一个双向链表来保存数据,表头表示最近使用过的数据,而表尾表示最近最少使用的数据。当用set插入数据时,先在其中查找是否存在,如果存在则将其移动到表头后面;如果不存在则将其插入到表头后面,并且将表尾前面的元素删除。当用get返回数据时,查看是否存在,如果存在,先将其移动到表头,再返回该值,不存在则返回null. 具体代码如下:
1 class LRUCache{ 2 public: 3 LRUCache(int capacity) 4 { 5 if(capacity < 1) return; 6 head = new link(0, 0); 7 tail = new link(0, 0); 8 head->next = tail; 9 tail->pre = head; 10 mp.clear(); 11 size = 0; 12 cap = capacity; 13 } 14 15 int get(int key) 16 { 17 map<int, link*>::iterator it = mp.find(key); 18 if (it != mp.end()) { 19 link* cur = (*it).second; 20 moveToHead(cur); 21 return cur->value; 22 } else 23 return -1; 24 } 25 26 void set(int key, int value) 27 { 28 if (cap < 1) return; 29 map<int, link*>::iterator it = mp.find(key); 30 if (it != mp.end()) 31 { 32 link* cur = (*it).second; 33 cur->value = value; 34 moveToHead(cur); 35 } 36 else 37 { 38 link* tmp = new link(key,value); 39 insertHead(tmp); 40 mp[key] = tmp; 41 if (size < cap) 42 { 43 size++; 44 } 45 else 46 { 47 link* deltmp = tail->pre; 48 tail->pre = deltmp->pre; 49 deltmp->pre->next = tail; 50 it = mp.find(deltmp->key); 51 mp.erase(it); 52 delete deltmp; 53 } 54 } 55 } 56 void moveToHead(link* cur) 57 { 58 cur->pre->next = cur->next; 59 cur->next->pre = cur->pre; 60 insertHead(cur); 61 } 62 void insertHead(link* cur) 63 { 64 cur->next = head->next; 65 head->next->pre = cur; 66 cur->pre = head; 67 head->next = cur; 68 } 69 private: 70 map<int,link*> mp; 71 int size; 72 int cap; 73 link* head; 74 link* tail; 75 }; 76 struct link 77 { 78 link* pre; 79 link* next; 80 int key; 81 int value; 82 link(int key,int value):key(key),value(value), 83 pre(NULL),next(NULL) 84 {}; 85 };
上述函数主要用到容器map的find函数实现通过key来找到对应value的功能,其余的就是双链表的插入与删除操作,都是基本的数据结构知识。