<span style="font-size:18px;"><span style="font-size:18px;background-color: rgb(255, 255, 255);">#ifndef _LRUCACHE_
#define _LRUCACHE_
#include<hash_map>
using namespace std;
/*以双链表实现LRUCache,以hash_map为对象容器,提供快速读取。*/
template<typename K,typename V>
struct LRUCacheNote
{
LRUCacheNote(K k,V v):key(k),value(v) {
prev=nullptr;
next=nullptr;
}
LRUCacheNote():key(K()),value(V()) {
prev=nullptr;
next=nullptr;
}
LRUCacheNote* prev;//前驱指针
LRUCacheNote* next;//后继指针
K key;
V value;
};
template<typename K,typename V>
class LRUCache
{
public:
LRUCache(int size):maxsize(size),currentsize(0) {
first=nullptr; //即为空链表
last=nullptr;
}
LRUCacheNote<K,V> get(K key); //取出指定note,并把其移到链表头
void put(K key,V value); //插入一个节点到链表头
void remove(K key); //删除指定节点
void removelast(); //删除最久没被用到的节点(链表尾节点)
void MvoeToHead(LRUCacheNote<K,V>& note);//指定节点移到链表头
void clear(); //清空容器
int capcity(){return this->currentsize;}; //返回当前容量
hash_map<K, LRUCacheNote<K,V>* >& getmap(){return this->map;} //返回对象容器
LRUCacheNote<K,V>* getfirst(){return this->first;} //获取头指针
LRUCacheNote<K,V>* getlast(){return this->last;} //获取尾部指针
private:
LRUCacheNote<K,V>* first;//头结点指针
LRUCacheNote<K,V>* last;//尾节点指针
const int maxsize;//对象容器最大容量
int currentsize;//当前容器容量
hash_map<K, LRUCacheNote<K,V>* > map;//对象容器 存入节点指针而非节点对象</span></span>
<span style="font-size:18px;"><span style="font-size:18px;background-color: rgb(255, 255, 255);">
};
/***********************************************************************/
//LRUCache方法实现:
template<typename K,typename V>
LRUCacheNote<K,V> LRUCache<K,V>::get(K key)
{
LRUCacheNote<K,V>* note=map.at(key);
if(this->map.find(key)!=this->map.end())
{
this->MvoeToHead(*note);
return *note;
}
else
{
cout<<"This list is empty!";
return LRUCacheNote<K,V>();
}
}
template<typename K,typename V>
void LRUCache<K,V>::put(K key,V value)
{
LRUCacheNote<K,V>* pnote=new LRUCacheNote<K,V>(key,value);
if(this->map.find(key)!=map.end())//元素已有,则直接移到头部
{
this->MvoeToHead(*pnote);
return ;
}
else if(this->currentsize==0)//没有则插入到头部,原来为空链表
{
this->first=pnote;
this->last=pnote;
++(this->currentsize);
this->map.insert(make_pair(key,pnote));//注意插入的是 拷贝
}
else//原来非空
{
pnote->prev=first;
this->first->next=pnote;
this->first=pnote;
++(this->currentsize);
this->map.insert(make_pair(key,pnote));
}
if(this->currentsize > this->maxsize)//容器溢出,删除尾元素
this->removelast();
}
template<typename K,typename V>
void LRUCache<K,V>::MvoeToHead(LRUCacheNote<K,V>& note)
{
if(note.key==this->first->key)//已经在头部
return;
else if(note.key==this->last->key)//在尾部
{
note.next->prev=note.prev;
this->last=note.next;
note.prev=this->first;
// this->first->prev=¬e;
this->first->next=¬e;
note.next=nullptr;
this->first=¬e;
}
else//不在头尾
{
note.next->prev=note.prev;
note.prev->next=note.next;
note.prev=this->first;
// this->first->prev=¬e;
this->first->next=¬e;
note.next=nullptr;
this->first=¬e;
}
}
template<typename K,typename V>
void LRUCache<K,V>::removelast()
{
if(first==nullptr)//空链表
return ;
else if(this->first==this->last)//只有一个节点
{
LRUCacheNote<K,V>* p=this->last;
this->first=nullptr;
this->last=nullptr;
this->map.erase(p->key);
--(this->currentsize);
}
else
{
LRUCacheNote<K,V>* p=this->last;
(this->last->next)->prev=nullptr;
this->last=this->last->next;
this->map.erase(p->key);
--(this->currentsize);
}
}
template<typename K,typename V>
void LRUCache<K,V>::remove(K key)
{
if(first==nullptr)//空链表
return ;
else
{
LRUCacheNote<K,V>& note=*(this->map.at(key));
if(this->map.find(key)==map.end())//不存在该节点
return;
else
{
if(this->first==this->last)//只有一个节点
{
this->first=nullptr;
this->last=nullptr;
}
else if(key==this->first->key)//为头节点
{
// note.prev->next=note.next;
note.prev->next=note.next;
this->first=note.prev;
}
else if(key==this->last->key)//为尾节点
{
note.next->prev=nullptr;
this->last=note.next;
}
else
{
note.next->prev=note.prev;
note.prev->next=note.next;
}
this->map.erase(key);
--(this->currentsize);
}
}
}
template<typename K,typename V>
void LRUCache<K,V>::clear()
{
this->first=nullptr;
this->last=nullptr;
this->map.clear();
this->currentsize=0;
}
#endif </span></span>
<span style="font-size:18px;"></pre><pre name="code" class="cpp"><span style="font-size:18px;background-color: rgb(255, 255, 255);">/*******************************基本功能测试*********************************************/<pre name="code" class="cpp">#include"LRUCache.h"
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1="aaa";
string s2="bbb";
string s3="ccc";
LRUCache<int,string> l(5);
l.put(1,s1);
l.put(2,s2);
l.put(3,s3);
l.put(4,"ddd");
//从链表输出
LRUCacheNote<int,string>* p1=l.getfirst();
for(int i=0;i<l.capcity();++i)
{
cout<<p1->value<<endl;
p1=p1->prev;
}
//从hash_map输出
for(auto i:l.getmap())
cout<<i.second->value<<endl;
//移到头部
cout<<"MvoeToHead:"<<endl;
l.MvoeToHead(*(l.getmap().begin()->second));
LRUCacheNote<int,string>* p2=l.getfirst();
for(int i=0;i<l.capcity();++i)
{
cout<<p2->value<<endl;
p2=p2->prev;
}
//读取指定key节点
cout<<"get(3):"<<l.get(3).value<<endl;
LRUCacheNote<int,string>* p3=l.getfirst();
for(int i=0;i<l.capcity();++i)
{
cout<<p3->value<<endl;
p3=p3->prev;
}
//删除节点
cout<<"remove(2):"<<endl;
l.remove(2);
LRUCacheNote<int,string>* p4=l.getfirst();
for(int i=0;i<l.capcity();++i)
{
cout<<p4->value<<endl;
p4=p4->prev;
}
//从hash_map输出
for(auto i:l.getmap())
cout<<i.second->value<<endl;
l.put(100,"are you ok?");
//从链表输出
cout<<"put():"<<endl;
LRUCacheNote<int,string>* p5=l.getfirst();
for(int i=0;i<l.capcity();++i)
{
cout<<p5->value<<endl;
p5=p5->prev;
}
//链表逆向输出
LRUCacheNote<int,string>* p6=l.getlast();
for(int i=0;i<l.capcity();++i)
{
cout<<p6->value<<endl;
p6=p6->next;
}
//从hash_map输出
for(auto i:l.getmap())
cout<<i.second->value<<endl;
}</span></span>
*****************************************************************/