LRUCache初步实现

<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>

*****************************************************************/

                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值