您的位置:首页 > 编程语言 > C语言/C++

C++实现LRU缓存策略思路+代码

2020-07-15 05:02 447 查看

实现LRU缓存策略

LRU缓存策略

英文全称Least Recently Used,是页面置换算法的一种,即淘汰掉最长时间不使用的页面。在缓存中,是一种缓存淘汰策略,优先删除很久没有用过的数据。

实现思路分析

设计

put
get
方法,实现O(1)时间的查找插入删除,应该用散列表;但散列表是无序的,要实现有序性,应该用链表结构。因此,一个哈希链表的结构符合我们的要求。

实现代码

题目来源:LeetCode 146
解法来源:LeetCode用户 labuladong

  • 所需的数据结构(双向链表)
//双向链表
struct Node{
size_t  key, val;
Node* next;
Node* pre;
Node(size_t k, size_t v): key(k), val(v), next(nullptr), pre(nullptr) {}
};
  • 双向链表需要的一些接口函数
class DoubleList{
private:
Node head, tail;  //头尾哨兵节点
size_t  size;  //链表长度
public:
//新建双向链表
DoubleList(){
head = new Node(0,0);
tail = new Node(0,0);
head->next = tail;
tail->pre = head;
size = 0;
}
//在头部添加节点
void addToHead(Node n){
Node* temp = head->next;
n->next = temp;
temp->pre = n;
n->pre = head;
head->next = x;
size++;
}
//删除链表中n节点
void deleteNode(Node n){
Node* temp = n->next;
n->pre->next = temp;
temp->pre = n->pre;
size--;
delete n;
}
//删除链表最后一个节点并返回
Node* deleteLast(){
if(tail->pre==head) return nullptr;
Node* last = tail->pre;
last->pre->next = tail;
tail->pre = last->pre;
delete last;
return last;
}
size_t getSize(){
return size;
}
};
  • 实现逻辑
    size = 2
    容量大小为2
    put(1,1),put(2,2);
    把1和2 放进缓存中
    get(1,1) return 1;
    查找1,找到返回1;
    put(3,3);
    此时废除2
    get(2,2) return -1;
    2已被废除,找不到返回-1
LRUCache(int capacity) {
}
//key和Node映射
unordered_map<size_t k, Node* pNode> hashmap;
DoubleList cache;
int get(int key){
//没找到返回-1
if(hashmap.find(key)==hashmap.end())  return -1;
//找到了就把数据提到开头
else{
cache.addToHead(hashmap[key]);
return hashmap[key]->val;
}
}

int put(int key, int val){
Node x = new Node(key, val);  //新插入的节点 x
//如果插入的key已经存在就把旧的数据删除再插入,不存在就直接插入即可
if(hashmap.find(key)!=hashmap.end()){
cache.delete(hashmap[key]);
cache.addToHead(x);
}
else{
//如果cache满了,那就删除链表最后一个位置
if(cache.getSize()==capcity){
cache.deleteLast();
}
cache.addToHead(x);
hashmap[key] = x;
}
}

C++解法(list+unordered_map)

class LRUCache {
private:
int cap;
list<pair<int, int>> cache;  //双向链表
unordered_map<int key, list<pair<int, int>::iterator> > hashmap;
}
public:
LRUCache(int capacity) {
this->cap = capacity;
}
int get(int key){
auto it = hashmap[key];
if(it==hashmap.end()) return -1;  //没找到
pair<int, int> kv = *hashmap[key];
cache.erase(map[key]);
cache.push_front(kv);
hashmap[key] = cache.begin();  //map中存的是迭代器,注意这一点!!
return kv.second;
}
void put(int key, int value){
auto it = hashmap[key];
if(it==hashmap.end()){
if(cache.size()==cap){
auto lastPair = cache.back();
map.erase(lastPair.first);
cache.pop_back();
}
cache.push_front(make_pair<key, value>);
hashmap[key] = cache.begin();
}
else{
cache.erase(map[key]);
cache.push_front(make_pair<key, value>);
hashmap[key] = cache.begin();
}
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: