LRU算法的一种实现方法
一,说明
LRU即最近未使用算法,是一种比较常用的内存管理算法,它在内存不足时通过唤出最近未使用的数据来确保新的数据可存储进去,说白了就是一种按进入内存的时候来淘汰数据和方法,所以得有一种数据结构来按顺序来存储数据,双向链表是一种很好的选择。
二,源码
源码中采用stl::list双向链表来存储数据,unordered_map来存储key到数据的映射关系。 get操作的时间复杂度是o(1), set操作的时候复杂度在cache没有命中时为o(n),所以set的时候复杂度为O(N)
/*************************************************************************
> File Name: LRUCache.cpp
> Author:zhangtx
> Mail: 18510665908@163.com
> Created Time: 2018年04月13日 星期五 10时52分19秒
************************************************************************/
#include<iostream>
#include <map>
#include <list>
using namespace std;
struct Data
{
int m_key;
int m_data;
};
class LRUCache {
public:
/*
* @param capacity: An integer
*/LRUCache(int capacity):m_capacity(capacity),m_count(0) {
// do intialization if necessary
}
/*
* @param key: An integer
* @return: An integer
*/
int get(int key) {
// write your code here
map<int,Data*>::iterator iter=m_data.find(key);
if (iter != m_data.end())
{
move_to_list_head(iter->second);
return iter->second->m_data;
}
else
return -1;
}
/*
* @param key: An integer
* @param value: An integer
* @return: nothing
*/
void set(int key, int value) {
// write your code here
map<int,Data *>::iterator iter=m_data.find(key);
if (iter != m_data.end())
{
Data *pdata=new Data;
pdata->m_key = key;
pdata->m_data = value;
m_data[key]=pdata;
move_to_list_head(iter->second);
}
else
{
if (m_count>=m_capacity)
remove_data();
Data *pdata=new Data;
pdata->m_data = value;
pdata->m_key = key;
m_data[key] = pdata;
m_list.push_front(pdata);
m_count++;
}
return ;
}
void remove_data()
{
Data *data=m_list.back();
m_list.pop_back();
m_data.erase(data->m_key);
delete data;
m_count--;
}
void move_to_list_head(struct Data *data)
{
list<Data*>::iterator iter=m_list.begin();
for (;iter!=m_list.end(); iter++)
{
if ((*iter)->m_key==data->m_key)
break;
}
m_list.push_front(m_data[(*iter)->m_key]);
m_list.erase(iter);
}
private:
map<int,Data *> m_data;
list<Data*> m_list;
int m_capacity;
int m_count;
};
int main(int argc,char *argv[])
{
LRUCache lRUCache(2);
lRUCache.set(2,1);
lRUCache.set(1,2);
cout<<lRUCache.get(2);
lRUCache.set(4,1);
cout<<lRUCache.get(1);
cout<<lRUCache.get(2);
}