LRU缓存结构【C语言】

c 复制代码
#include <stdio.h>
#include <stdlib.h>

//双链表节点结构
typedef struct Node {
	int key;
	int value;
	struct Node* pre;
	struct Node* next;
} Node;

//LRU结构
typedef struct 
{
	int capacity;
	struct Node* head;
	struct Node* tail;
	struct Node** cache;
}LRUCache;

//创建新节点
Node* createNode(int key, int value)
{
	Node* newNode = (Node*)malloc(sizeof(Node));
	newNode->key = key;
	newNode->value = value;
	newNode->pre = NULL;
	newNode->next = NULL;
	return newNode;
}

//创建LRU缓存
LRUCache* creatLRUCache(int capacity)
{
	LRUCache* cache = (LRUCache*)malloc(sizeof(LRUCache));
	cache->capacity = capacity;
	cache->head = createNode(0, 0);
	cache->tail = createNode(0, 0);
	cache->head->next = cache->tail;
	cache->tail->pre = cache->head;

	cache->cache = (Node**)malloc(sizeof(Node*)*100001);
	for (int i = 0; i < 100001; i++)
	{
		cache->cache[i] = NULL;
	}
	return cache;
}

//删除节点
void deleteNode(Node* node)
{
	node->pre->next = node->next;
	node->next->pre = node->pre;
}

//插入节点到头部
void insertToHead(Node* node, Node* head)
{
	node->next = head->next;
	node->pre = head;
	head->next = node;
	node->next->pre = node;
}

int getLRUCacheValue(LRUCache* obj, int key)
{
	if (obj->cache[key] != NULL)
	{
		Node* node = obj->cache[key];
		deleteNode(node);
		insertToHead(node, obj->head);
		return node->value;
	}
	return -1;
}

void setLRUCacheValue(LRUCache* obj, int key, int value)
{
	if (obj->cache[key] != NULL)
	{
		Node* node = obj->cache[key];
		node->value = value;
		deleteNode(node);
		insertToHead(node, obj->head);
	}
	else
	{
		Node* newNode = createNode(key, value);
		obj->cache[key] = newNode;
		insertToHead(newNode, obj->head);
		if(obj->capacity-- == 0)
		{
			Node* tail = obj->tail->pre;
			deleteNode(tail);
			obj->cache[tail->key] = NULL;
			free(tail);
			obj->capacity++;
		}
	}
}

//释放内存
void LRUCacheFree(LRUCache* obj)
{
	for (int i = 0; i < 100001; i++)
	{
		if (obj->cache[i] != NULL)
		{
			free(obj->cache[i]);
		}
	}
	free(obj->cache);
	free(obj->head);
	free(obj->tail);
	free(obj);
}

int main()
{
	LRUCache* obj = creatLRUCache(2);
	setLRUCacheValue(obj, 1, 1);
	setLRUCacheValue(obj, 2, 2);
	printf("%d\n", getLRUCacheValue(obj, 1));
	setLRUCacheValue(obj, 3, 3);
	printf("%d\n", getLRUCacheValue(obj, 2));
	setLRUCacheValue(obj, 4, 4);
	printf("%d\n", getLRUCacheValue(obj, 1));
	printf("%d\n", getLRUCacheValue(obj, 3));
	printf("%d\n", getLRUCacheValue(obj, 4));
	LRUCacheFree(obj);
	system("pause");
	return 0;
}

参考:https://blog.csdn.net/Conner7/article/details/136572016

相关推荐
了一梨2 小时前
在Ubuntu中配置适配泰山派的交叉编译环境
linux·c语言·ubuntu
爬山算法2 小时前
Redis(162)如何使用Redis实现消息队列?
数据库·redis·缓存
郑州光合科技余经理2 小时前
同城系统海外版:一站式多语种O2O系统源码
java·开发语言·git·mysql·uni-app·go·phpstorm
u***32432 小时前
【Redis】centos7 systemctl 启动 Redis 失败
数据库·redis·缓存
CQ_YM2 小时前
数据结构之单向链表
c语言·数据结构·链表
一只乔哇噻2 小时前
java后端工程师+AI大模型开发进修ing(研一版‖day60)
java·开发语言·人工智能·学习·语言模型
LNN20222 小时前
Linuxfb+Qt 输入设备踩坑记:解决 “节点存在却无法读取“ 问题
开发语言·qt
踢足球09292 小时前
Redis的典型应用
数据库·redis·缓存
O***P5713 小时前
redis批量删除namespace下的数据
数据库·redis·缓存
foxsen_xia3 小时前
go(基础06)——结构体取代类
开发语言·算法·golang