目次
LRU アルゴリズム
局所性の原則に基づいて、最近アクセスされたメモリは将来再びアクセスされる可能性があります。
そのため、データを削除する場合は、使用されていない期間が最も長いデータを優先して削除します。
実装のアイデア
二重連結リストを使用して、最近使用されたデータをチェーンの先頭にマウントし、最も長く使用されていないデータがキューの最後に来るようにし、データを削除するときにキューの最後にある要素を削除します。
キーキーをすばやく見つけるにはリンクされたリスト内のキーの位置。ハッシュ テーブルを使用してキーを記録できます−ノード キー-ノードキーとキー−ノードマッピング. _ _
トピック
コード
class LRUCache
{
public:
struct DListNode
{
int key, value; //事实上key值没有使用
DListNode *pre;
DListNode *next;
DListNode() {
}
DListNode(int a, int b) {
key = a, value = b; }
};
unordered_map<int, DListNode *> mp; // key-Node 映射
int MAX_SIZE;
DListNode *HEAD;
DListNode *TAIL;
LRUCache(int capacity) //初始化双向链表
{
MAX_SIZE = capacity;
HEAD = new DListNode;
TAIL = new DListNode;
HEAD->next = TAIL;
TAIL->pre = HEAD;
}
int get(int key)
{
if (!mp.count(key)) //如果该key不存在,返回-1
return -1;
DListNode *tmp = mp[key]; //将这个结点调整到链表头部
tmp->pre->next = tmp->next;
tmp->next->pre = tmp->pre;
tmp->next = HEAD->next;
tmp->pre = HEAD;
HEAD->next = tmp;
tmp->next->pre = tmp;
return mp[key]->value;
}
void put(int key, int value)
{
if (!mp.count(key)) //如果之前不在缓存,创建并放到链头
{
DListNode *tmp = new DListNode(key, value); //将这个结点放到链表头部
mp[key] = tmp;
tmp->pre = HEAD;
tmp->next = HEAD->next;
HEAD->next->pre = tmp;
HEAD->next = tmp;
if (mp.size() > MAX_SIZE) //超过容量,需要删除链表尾部结点
{
mp.erase(TAIL->pre->key);
TAIL->pre->pre->next = TAIL;
TAIL->pre = TAIL->pre->pre;
}
}
else //已经存在,调整到链表头部
{
DListNode *tmp = mp[key];
tmp->value = value;
tmp->pre->next = tmp->next;
tmp->next->pre = tmp->pre;
tmp->next = HEAD->next;
tmp->pre = HEAD;
HEAD->next->pre = tmp;
HEAD->next = tmp;
}
}
};