LRU介绍
LRU是Least Recently Used 近期最少使用算法。 内存管理的一种页面置换算法,对于在内存中但又不用的数据块(内存块)叫做LRU,操作系统会根据哪些数据属于LRU而将其移出内存而腾出空间来加载另外的数据。
利用一个双向链表<c++ list>和一个HashMap<c++ unordered_map>来快速定位数据:
- set数据时候,需要先看是否已经有key对应元素,如果有,则需要更改value值,由于LRU,所以需要把这个元素放到链表的表头,可以先删除再创建到表头,也可以利用list的splice方法进行移动
- get数据时候需要看是否存在key,不存在返回-1即可,存在需要进行移动,可以先删除然后创建链表头元素,也可以splice进行移动数据。
list介绍
c++中list是双向链表的实现,具有以下方法:
// 将x的i处的元素移动到position处,替代删除然后插入
void splice (iterator position, list& x, iterator i);
// 删除数据: 某个位置,链表尾部,链表头部
iterator erase (iterator position);
void pop_back();
void pop_front();
// 获取元素
reference back();
reference front();
// 链表尾部&头部插入数据,中间位置插入
void push_back (const value_type& val);
void push_front (const value_type& val);
iterator insert (iterator position, const value_type& val);
// 遍历
begin end
代码实现
删除重建方式:
class LRUCache {
private:
int _capacity;
list<pair<int, int>> items;
unordered_map<int, list<pair<int, int>>::iterator> mmap;
public:
LRUCache(int capacity) {
_capacity = capacity;
}
int get(int key) {
if (mmap.count(key)) {
int value = mmap[key]->second;
items.erase(mmap[key]);
items.push_front(make_pair(key, value));
mmap[key] = items.begin();
return value;
} else {
return -1;
}
}
void put(int key, int value) {
if (mmap.count(key) == 0) {
if (mmap.size() == _capacity) {
mmap.erase(items.back().first);
items.pop_back();
}
items.push_front(make_pair(key, value));
mmap[key] = items.begin();
} else {
items.erase(mmap[key]);
items.push_front(make_pair(key, value));
mmap[key] = items.begin();
}
}
};
利用splice方法优化方法:
class LRUCache {
private:
int _capacity;
list<pair<int, int>> items;
unordered_map<int, list<pair<int, int>>::iterator> mmap;
public:
LRUCache(int capacity) {
_capacity = capacity;
}
int get(int key) {
if (mmap.count(key)) {
items.splice(items.begin(), items, mmap[key]);
mmap[key] = items.begin();
return mmap[key]->second;
} else {
return -1;
}
}
void put(int key, int value) {
if (mmap.count(key) == 0) {
if (mmap.size() == _capacity) {
mmap.erase(items.back().first);
items.pop_back();
}
items.push_front(make_pair(key, value));
mmap[key] = items.begin();
} else {
mmap[key]->second = value;
items.splice(items.begin(), items, mmap[key]);
mmap[key] = items.begin();
}
}
};