当前位置:网站首页>【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;
}
};
边栏推荐
- 全文检索引擎Solr系列—–全文检索基本原理
- Redis: operation command of string type data
- Too many files with unapproved license
- 别再问自己适不适合做软件测试了
- simpleParallax. JS (create poor visual effects for website pictures)
- Exercise 10-8 recursive implementation of sequential output of integers
- Etcd cluster permission management and account password usage
- Thinking about the arrangement problem in the backtracking problem (leetcode questions 46 and 47)
- Solr series of full-text search engines - basic principles of full-text search
- Stop asking yourself if you are suitable for software testing
猜你喜欢

Exercise 6-6 use a function to output an integer in reverse order

关于回溯问题中的排列问题的思考(LeetCode46题与47题)

x86汇编语言-从实模式到保护模式 笔记

Redis: redis data structure and key operation commands

Accelerating strategy learning using parallel differentiable simulation

Bibit pharmaceutical rushed to the scientific innovation board: annual revenue of 970000, loss of 137million, proposed to raise 2billion

Exercise 7-6 count capital consonants

Doris学习笔记之数据表的创建

NPM install is stuck with various strange errors of node NPY

Exercise 10-6 recursively find Fabonacci sequence
随机推荐
Webpage connection database ~ simple implementation of addition, deletion, modification and query complete code
Raft agreement
Leetcode(4)——寻找两个正序数组的中位数
Sendmail无法发送邮件及发送过慢解决
X86 assembly language - Notes from real mode to protected mode
7-18 finding the single root of polynomial by dichotomy
虽然不一定最优秀,但一定是最努力的!
必贝特医药冲刺科创板:年营收97万亏损1.37亿 拟募资20亿
Preliminary summary of structure
Exercise 6-1 classify and count the number of characters
【北大青鸟昌平校区】互联网行业中,哪些岗位越老越吃香?
7-23 currency conversion (using array conversion)
ZABBIX saves the page blank after adding calculated items
Solution to failure or slow downloading of electron when electron uses electron builder to package
天谋科技 Timecho 完成近亿元人民币天使轮融资,打造工业物联网原生时序数据库
动态获取权限
556. 下一个更大元素 III
7-15 calculation of PI
Statistical capital consonants
7-24 reduction of the simplest fraction (rolling Division)