LeetCode-146 LRU缓存机制

LRU缓存机制

在这里插入图片描述
使用hash_map和双向链表来做这题

class LRUCache {
public:
	//使用双向链表和哈希表结合
	class CacheNode
	{public:
		CacheNode* pre;
		CacheNode* next;
		int key;
		int value;
		CacheNode(int k,int v):key(k),value(v),pre(NULL),next(NULL) {}
	};
	int cachesize;
	int currentsize;
	unordered_map<int,CacheNode*> nodes;
	CacheNode* head ;
	CacheNode* last;
	LRUCache(int capacity) {
		//初始化缓冲区列表的操作
		cachesize = capacity;
		currentsize = 0;
		head = NULL;
		last = NULL;
		//nodes =unordered_map<int, CacheNode*>(capacity);//构造函数调用
	}
	//获取某个节点如果存在返回并且把该节点放到链表头,不存在返回-1
	int get(int key) {
		auto index = nodes.find(key);
		int result = -1;
		if (index!=nodes.end())
		{
			CacheNode* node = index->second;
			if (node == Gethead())
				return node->value;
			else
			{
				remove(node);
				Sethead(node);
			}	
			return node->value;
		}
		return result;
	}
	//将数据放入map中和链表中
	void put(int key, int value) 
	{
		//将节点组合成链表中的节点的数据格式的方式
		auto it = nodes.find(key);
		CacheNode* node;
		if (it!= nodes.end())//如果找到的话
		{
			node = it->second;//当前访问的节点
			if (node == Gethead())
			{
				node->value = value;
				return;
			}				
			else
			{
				node->value = value;
				remove(node);
				Sethead(node);
			}
		}
		else//没找到的话就建立这个节点的数据结构
		{
			node = new CacheNode(key, value);
			if (nodes.size() == cachesize)//如果到顶了需要删除尾结点
			{
				auto it1 = nodes.find(last -> key);
				remove(last);
				//现在更新last节点
				nodes.erase(it1);//这里为什么删除的是1
			}
			Sethead(node);
			nodes[key] = node;


		}
	}
	//将节点从双向链表中拿出来
	void remove(CacheNode* node)
	{
		if (node->pre == NULL)
		{
			head = node->next;
		}
        else
            node->pre->next=node->next;
		if (node->next == NULL)
			last = node->pre;
        else
            node->next->pre=node->pre;
		
	}
	CacheNode* Gethead()
	{
		return head;
	}
	//更新last和head的
	void Sethead(CacheNode* node)
	{
		//设置头结点的操作
		if (head == NULL)
		{
			head = node;
			last = node;
		}
		else
		{
			node->next = head;
			head->pre = node;
			head = node;
		}	
	}
};

在这里插入图片描述

参考:

https://www.cnblogs.com/Hwangzhiyoung/p/9305786.html

https://blog.csdn.net/wk_bjut_edu_cn/article/details/84834686

//LRU实现使用双向链表和哈希函数:为什么??
class LRUCache {
public:
	//
	LRUCache(int capacity) {
		cap = capacity;
	}

	int get(int key) {//获得是否存在,存在的话将它拿出来然后放到list的首部
		int retval = -1;
		auto it = cachemap.find(key);
		if (it != cachemap.end())//如果找得到的话
		{
			retval = it->second->second;//返回的数值是
			list<pair<int, int>>::iterator del = it->second;
			pair<int, int> tmpdel = *del;//是一个链表中的pair
			caches.erase(del);//删除的是迭代器d
			caches.push_front(tmpdel);
			cachemap[key] =caches.begin() ;
			return retval;
		}
		else//不存在的话,返回-1
		{

			return retval;
		}
	}

	void put(int key, int value) {
		auto it = cachemap.find(key);
		if (it != cachemap.end())//如果存在的话
		{
			list<pair<int, int>>::iterator temp = it->second;
			pair<int, int> tempdel = *temp;//
			caches.erase(temp);
			caches.push_front(tempdel);
			cachemap[key] = caches.begin();
		}
		else//如果不存在的话
		{
			//需要构造一个cachemap中的元素来进行计算
			//因为需要cap影响所以
			pair<int, int> charu = pair<int, int>(key, value);
			if (cachemap.size() <= cap)
			{
				//首先获得一下要删除的Key,因为需要使用这个key删除cachemap中
				int temp = caches.back().first;
				caches.pop_back();
				unordered_map<int, list<pair<int, int>>::iterator>::iterator delit = cachemap.find(temp);
				cachemap.erase(delit++);
			}
			caches.push_front(charu);
			cachemap[key] = caches.begin();
		}
	}
private:
	unordered_map<int, list<pair<int, int>>::iterator> cachemap;
	int cap;
	list<pair<int, int> > caches;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值