LFU的实现(c++实现)

#include
#include
using namespace std;
//初始化缓存节点信息
struct Node {
	int key, val, freq;
	Node(int _key, int _val, int _freq) :key(_key), val(_val), freq(_freq) {}
};
class LFUCache
{
private:
	int minfreq;  //当前缓存中使用的最少的频率值
	int capacity;  //容量

	//以键值 key 为索引,每个索引存放对应缓存在 FreqTable中链表里的地址,
	unordered_map::iterator> KeyTable;
	//以频率 freq 为索引,每个索引存放一个双向链表 双向链表的数据域中 存放node结构体
	unordered_map> FreqTable;
public:
	LFUCache(int _capcity) {
		minfreq = 0;
		capacity = _capcity;
		KeyTable.clear();
		FreqTable.clear();
	}
	int get(int key) {
		if (capacity == 0)
			return -1;
		auto keyIter = KeyTable.find(key);
		if (keyIter == KeyTable.end())
			return -1;//找不到这个key值就返回-1
		list::iterator nodeIter = keyIter->second;
		int val = nodeIter->val, freq = nodeIter->freq;
		//删除FreqTable 中索引为freq的 nodeIter节点
		FreqTable[freq].erase(nodeIter);
		// 如果当前链表为空,我们需要在哈希表中删除,且更新minFreq
		if (FreqTable[freq].size() == 0) {
			FreqTable.erase(freq);
			if (minfreq == freq)
				minfreq++;
		}
		//插入到freq + 1中的前面
		FreqTable[freq + 1].push_front(Node(key, val, freq + 1));
		KeyTable[key] = FreqTable[freq + 1].begin();
		return val;
	}
	void put(int key, int val) {
		if (capacity == 0) return;
		auto keyIter = KeyTable.find(key);
		if (keyIter == KeyTable.end()) {  //找不到这个key值
		 //缓存满了 删除缓存
			if (KeyTable.size() == capacity) {
				// 通过 minFreq 拿到 freq_table[minFreq] 链表的末尾节点
				Node MinFreqBackNode = FreqTable[minfreq].back();
				//根据MinFreqBackNode的key值 删除 KeyTable中的键值对
				KeyTable.erase(MinFreqBackNode.key);
				FreqTable[minfreq].pop_back();
				// 如果当前链表为空,我们需要在哈希表中删除,且更新minFreq
				if (FreqTable[minfreq].size() == 0) {
					FreqTable.erase(minfreq);
				}
			}
			FreqTable[1].push_front(Node(key, val, 1));
			KeyTable[key] = FreqTable[1].begin();
			minfreq = 1;
		}
		else {		//如果找到这个key
			list::iterator nodeIter = keyIter->second;
			int  freq = nodeIter->freq;
			FreqTable[freq].erase(nodeIter);
			if (FreqTable[freq].size()==0)
			{
				FreqTable.erase(freq);
				if (minfreq == freq)
					minfreq++;
			}
			FreqTable[freq + 1].push_front(Node(key, val, freq + 1));
			KeyTable[key] = FreqTable[freq + 1].begin();
		}
	}
};
int main() {

	LFUCache cache = LFUCache(2);


	cout << "插入 key = 1,val=10" << endl;
	cache.put(1, 10);
	cout << "插入 key = 2,val=20" << endl;
	cache.put(2, 20);

	cout <<"查询key为1 对应的 val: " << cache.get(1) << endl;
	cout << "没有插入key为3的时候  查询key为3 对应的 val:" << cache.get(3) << endl;

	cout << "插入 key = 3,val=30" << endl;
	cache.put(3, 30);

	cout << "查询key为2 对应的 val"  << endl;
	if (cache.get(2) == -1)
	{
		cout << "key=2 已经被淘汰" << endl;
	}
	else {
		cout << "key=2 仍然存在" << endl;

	}
	system("pause");
	return 0;
}

参考

https://leetcode-cn.com/problems/lfu-cache/solution/lfuhuan-cun-by-leetcode-solution/官方题解

你可能感兴趣的:(数据结构)