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

LRU(近期最少使用算法)C++实现源码

2017-04-25 21:58 761 查看

写在前面

今天一同学去公司实习面试,面试官要求手写LRU算法,有些懵。在这里想写篇博客给他作为参考,同时也给大家作为参考。

LRU(最近最少使用算法)

LRU是CPU cache中n-way的一种替换规则(对cache不了解的可以查看https://en.wikipedia.org/wiki/CPU_cache),当有新成员加入时,它需要替换近期最少被使用的cache line。

双向链表+哈希表

这种方式比较常见,如图所示:



新数据或击中的数据放到链表头部,表示最近使用的数据,如果链表满,从尾部淘汰数据。但只用链表会存在一个问题,击中数据的时间复杂度为O(n),每次需要遍历链表,所以引入哈希表,时间复杂度降到O(1),以空间换时间。

#include <list>
#include <unordered_map>
#include <cassert>
using namespace std;
struct Element
{
int key;
int value;
Element(int k, int v):key(k), value(v){}
};
class LRUCache {
private:
list<Element> m_list;
unordered_map<int, list<Element>::iterator> m_map;
int m_capacity;
public:
LRUCache(int capacity) {
m_capacity = capacity;
}

int get(int key) {
if (m_map.find(key) == m_map.end())
return -1;
else
{
//将元素放入链表头部
m_list.splice(m_list.begin(), m_list, m_map[key]);
m_map[key] = m_list.begin();
return m_list.begin()->value;
}
}

void put(int key, int value) {
assert(m_capacity > 0);
if (m_map.find(key) != m_map.end())
{   //更value
m_map[key]->value = value;
//将元素放入链表头部
m_list.splice(m_list.begin(), m_list, m_map[key]);
m_map[key] = m_list.begin();
}
else if (m_capacity == m_list.size())
{
m_map.erase(m_list.back().key);
m_list.pop_back();
m_list.push_front(Element(key, value));
m_map[key] = m_list.begin();
}
else
{
m_list.push_front(Element(key, value));
m_map[key] = m_list.begin();
}
}
};

/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache obj = new LRUCache(capacity);
* int param_1 = obj.get(key);
* obj.put(key,value);
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构 算法 c++