基于双向链表和hashmap的LRU算法实现

基于双向链表和hashmap的LRU算法实现

什么是LRU

LRU缓存淘汰算法就是一种常用策略。LRU的全称是Least Recently Used,也就是说我们认为最近使用过的数据应该是有用的,很久都没用过的数据应该是无用的,缓存满了就优先删除那些很久没有用过的数据。

基于双向链表和hashmap的LRU算法实现

代码

#include<iostream>
#include<string>
#include<map>
#include<vector>
#include<stack>
using namespace std;
struct Node {
	int data;
	int key;
	Node *nextNode;
	Node *beforeNode;
};
struct MapLinkedList {
	int fullNum;
	int currentSize = 0;
	Node *begin;
	Node *last;
	map<int, Node*> myMap;
};
void init(MapLinkedList *&mapLinkedList) {
	mapLinkedList = new MapLinkedList();
	mapLinkedList->begin = new Node();
	mapLinkedList->fullNum = 10;
}
void destory(MapLinkedList *&mapLinkedList) {
	Node *temp = mapLinkedList->begin->nextNode;
	Node *temp_2;
	cout << "开始清除垃圾" << endl;
	while (temp!= NULL) {
		temp_2 = temp;
		cout << "清除 data:" << temp_2->data << "   key:" << temp_2->key << "..."<<endl;
		temp= temp->nextNode;
		delete temp_2;
	}
	delete mapLinkedList;
	cout << "清除完毕" << endl;
}
void visit(MapLinkedList *&mapLinkedList,int data,int key) {
	Node *newNode=new Node;
	newNode->data = data;
	newNode->key = key;
	newNode->nextNode = NULL;
	if (mapLinkedList->currentSize == 0) {
		cout << "当前容量为0" << endl;
		mapLinkedList->last = newNode;
		mapLinkedList->begin->nextNode = newNode;
		newNode->beforeNode = mapLinkedList->begin;
		mapLinkedList->myMap[key] = newNode;
		mapLinkedList->currentSize++;
	}
	else if (mapLinkedList->myMap[key] != NULL) {
		if (mapLinkedList->myMap[key] == mapLinkedList->last){
			if (mapLinkedList->currentSize !=1) {
				mapLinkedList->last = mapLinkedList->myMap[key]->beforeNode;
				mapLinkedList->last->nextNode = NULL;
				mapLinkedList->myMap[key]->nextNode = mapLinkedList->begin->nextNode;
				mapLinkedList->begin->nextNode->beforeNode= mapLinkedList->myMap[key];
				mapLinkedList->myMap[key]->beforeNode = mapLinkedList->begin;
				mapLinkedList->begin->nextNode = mapLinkedList->myMap[key];				
			}
		}
		else {
			mapLinkedList->myMap[key]->nextNode->beforeNode = mapLinkedList->myMap[key]->beforeNode;
			mapLinkedList->myMap[key]->beforeNode->nextNode = mapLinkedList->myMap[key]->nextNode;
			mapLinkedList->myMap[key]->nextNode = mapLinkedList->begin->nextNode;
			mapLinkedList->begin->nextNode->beforeNode = mapLinkedList->myMap[key];
			mapLinkedList->myMap[key]->beforeNode = mapLinkedList->begin;
			mapLinkedList->begin->nextNode = mapLinkedList->myMap[key];
		}
		cout << "当前容器中存在对应key的元素,将对应key提到链表头部" << endl;
	}
	else if(mapLinkedList->currentSize<mapLinkedList->fullNum){
		newNode->nextNode = mapLinkedList->begin->nextNode;
		mapLinkedList->begin->nextNode->beforeNode = newNode;
		mapLinkedList->begin->nextNode = newNode;
		newNode->beforeNode = mapLinkedList -> begin;
		mapLinkedList->myMap[key] = newNode;
		mapLinkedList->currentSize++;
		cout << "当前容器中没有新插入的元素,将新来的元素插入到链表头" << endl;
	}
	//超出最大容量
	else {
		//弹出最久未使用的块
		mapLinkedList->myMap[mapLinkedList->last->key] = NULL;
		Node* temp = mapLinkedList->last;
		mapLinkedList->last->beforeNode->nextNode = NULL;
		mapLinkedList->last = mapLinkedList->last->beforeNode;
		delete temp;
		mapLinkedList->currentSize--;
		//插入新块
		newNode->nextNode = mapLinkedList->begin->nextNode;
		mapLinkedList->begin->nextNode->beforeNode = newNode;
		mapLinkedList->begin->nextNode = newNode;
		newNode->beforeNode = mapLinkedList->begin;
		mapLinkedList->myMap[key] = newNode;
		mapLinkedList->currentSize++;
		cout << "当前容器的已装满,将最久未使用的key弹出链表" << endl;
	}
	cout << "插入节点成功,当前节点数为 " << mapLinkedList->currentSize << " ..."<<endl;
	cout << "所有节点为:" << endl;
	Node *temp = mapLinkedList->begin;
	while (temp->nextNode != NULL) {
		cout << "data:" << temp->nextNode->data << "   key:" << temp->nextNode->key << endl;
		temp = temp->nextNode;
	}
	cout << endl;
}
int main() {
	MapLinkedList *mapLinkedList=NULL;
	init(mapLinkedList);
	int data;
	int key;
	cout << "LRU模拟  输入-1 -1结束.." << endl;
	while (1) {
		cout << "请输入data和key:";
		cin >> data >> key;
		if (data == -1 || key == -1) {
			break;
		}
		visit(mapLinkedList, data, key);
	}
	destory(mapLinkedList);

	return 0;
}

执行效果

基于双向链表和hashmap的LRU算法实现

上一篇:删除链表中的节点


下一篇:循环双链表教程(个人笔记)