当前位置:网站首页>【7.3】146. LRU缓存机制
【7.3】146. LRU缓存机制
2022-07-03 14:19:00 【howtoloveyou】
方法:哈希表+双向链表
- 关键字:key,value对
- 模式识别:一旦出现键值对,就要想到哈希表
- 改变数据的访问时间:1 需要能够随机访问,2 需要能把该数据插到头部或者尾部
测试:
- 测试插入,包括溢出情况
- 测试更新,检查是否正确更新
- 测试读取,检测能否正确读取
hashmap+双向链表,复杂度分析:
- 时间复杂度:O1,哈希表定位O1,链表操作O1
- 空间复杂度:Oc
代码:
struct DLinkedNode {
int key, value;
DLinkedNode* prev;
DLinkedNode* next;
DLinkedNode(): key(0), value(0), prev(nullptr), next(nullptr) {
}
DLinkedNode(int _key, int _value): key(_key), value(_value), prev(nullptr), next(nullptr) {
}
};
class LRUCache {
private:
unordered_map<int, DLinkedNode*> cache;
DLinkedNode* head;
DLinkedNode* tail;
int size;
int capacity;
public:
LRUCache(int _capacity): capacity(_capacity), size(0) {
在初始化代码中的数据结构同时,初始化capacity和size两个参数
// 使用伪头部和伪尾部节点
head = new DLinkedNode(); 创建头部节点
tail = new DLinkedNode(); 创建尾部节点
head->next = tail; 头部-》尾部
tail->prev = head; 头部《-尾部
}
int get(int key) {
if (!cache.count(key)) {
如果没有则返回-1
return -1;
}
// 如果 key 存在,先通过哈希表定位,再移到头部
DLinkedNode* node = cache[key]; 通过哈希表定位再对节点进行操作
moveToHead(node); 这里将头部表示为最经常使用的元素
return node->value;
}
void put(int key, int value) {
if (!cache.count(key)) {
// 如果 key 不存在,创建一个新的节点
DLinkedNode* node = new DLinkedNode(key, value);
// 添加进哈希表
cache[key] = node;
// 添加至双向链表的头部
addToHead(node);
++size;
if (size > capacity) {
// 如果超出容量,删除双向链表的尾部节点
DLinkedNode* removed = removeTail();
// 删除哈希表中对应的项
cache.erase(removed->key);
// 防止内存泄漏
delete removed;
--size;
}
}
else {
// 如果 key 存在,先通过哈希表定位,再修改 value,并移到头部
DLinkedNode* node = cache[key];
node->value = value;
moveToHead(node);
}
}
void addToHead(DLinkedNode* node) {
node->prev = head;
node->next = head->next;
head->next->prev = node;
head->next = node;
}
void removeNode(DLinkedNode* node) {
node->prev->next = node->next;
node->next->prev = node->prev;
}
void moveToHead(DLinkedNode* node) {
removeNode(node);
addToHead(node);
}
DLinkedNode* removeTail() {
这里将最近没用过的节点提取出来,不会影响在哈希表中删除他的操作,因为他并没有消失
DLinkedNode* node = tail->prev;
removeNode(node);
return node;
}
};
边栏推荐
- Statistical capital consonants
- Sendmail can't send mail and it's too slow to send. Solve it
- Preliminary summary of structure
- JS Part 2
- Thinking about the arrangement problem in the backtracking problem (leetcode questions 46 and 47)
- Although not necessarily the best, it must be the hardest!
- Strategy, tactics (and OKR)
- 编程语言:类型系统的本质
- ConstraintLayout 的使用
- Concat and concat_ Ws() differences and groups_ Use of concat() and repeat() functions
猜你喜欢
随机推荐
玖逸云黑免费无加密版本源码
MySQL multi table query subquery
JS input number and standard digit number are compared. The problem of adding 0 to 0
556. 下一个更大元素 III
Thread. Sleep and timeunit SECONDS. The difference between sleep
Concat and concat_ Ws() differences and groups_ Use of concat() and repeat() functions
Solve the problem of dormitory router campus network sharing login
分布式事务(Seata) 四大模式详解
Exercise 10-2 recursive factorial sum
X86 assembly language - Notes from real mode to protected mode
allegro,orcad, net alias,port,off-page connector之间的异同点和如何选取
NFT新的契机,多媒体NFT聚合平台OKALEIDO即将上线
Onmenusharetimeline custom shared content is invalid, and the title and icon are not displayed
7-14 sum integer segments (C language)
TS code automatically generates JS
Toast UI editor (editor allows you to edit your markup document using text or WYSIWYG, with syntax highlighting, scrolling synchronization, real-time preview and chart functions.)
C language,%d% Difference between 2D%2d%02d
7-18 finding the single root of polynomial by dichotomy
【北大青鸟昌平校区】互联网行业中,哪些岗位越老越吃香?
Accelerating strategy learning using parallel differentiable simulation









