赞
踩
LRU(Least Recently Used,最近最少使用)缓存是一种缓存淘汰策略,用于管理缓存中数据的存储和淘汰。LRU缓存会优先淘汰最近最少使用的数据,以便为新数据腾出空间。它通常用于提高应用程序的性能,通过缓存常用的数据来减少对磁盘或数据库的访问次数。
下面是一个使用C语言实现的LRU缓存示例,展示了基本的插入、访问和删除操作。
首先,定义LRU缓存的数据结构和相关操作:
#include <stdio.h> #include <stdlib.h> // 定义缓存的最大大小 #define MAX_SIZE 3 // 双向链表节点 typedef struct Node { int key; int value; struct Node *prev; struct Node *next; } Node; // LRU缓存结构 typedef struct { Node *head; Node *tail; int size; Node *hashTable[MAX_SIZE]; // 哈希表,用于快速查找节点 } LRUCache; // 初始化LRU缓存 LRUCache *initLRUCache() { LRUCache *cache = (LRUCache *)malloc(sizeof(LRUCache)); cache->head = NULL; cache->tail = NULL; cache->size = 0; for (int i = 0; i < MAX_SIZE; i++) { cache->hashTable[i] = NULL; } return cache; } // 释放LRU缓存 void freeLRUCache(LRUCache *cache) { Node *current = cache->head; while (current != NULL) { Node *next = current->next; free(current); current = next; } free(cache); } // 将节点移动到链表的头部 void moveToHead(LRUCache *cache, Node *node) { if (cache->head == node) { // 节点已经在头部 return; } // 将节点从当前位置移除 if (node->prev != NULL) { node->prev->next = node->next; } else { cache->head = node->next; } if (node->next != NULL) { node->next->prev = node->prev; } else { cache->tail = node->prev; } // 将节点插入到头部 node->prev = NULL; node->next = cache->head; if (cache->head != NULL) { cache->head->prev = node; } cache->head = node; if (cache->tail == NULL) { cache->tail = node; } } // 插入键值对到缓存中 void put(LRUCache *cache, int key, int value) { int hashIndex = key % MAX_SIZE; Node *node = cache->hashTable[hashIndex]; while (node != NULL) { if (node->key == key) { // 键已存在,更新值并移动到头部 node->value = value; moveToHead(cache, node); return; } node = node->next; } // 键不存在,创建新节点 node = (Node *)malloc(sizeof(Node)); node->key = key; node->value = value; node->prev = NULL; node->next = NULL; // 将新节点插入到头部 moveToHead(cache, node); cache->hashTable[hashIndex] = node; cache->size++; // 如果缓存已满,删除最近最少使用的节点 if (cache->size > MAX_SIZE) { Node *tailNode = cache->tail; // 从哈希表中移除 int tailHashIndex = tailNode->key % MAX_SIZE; cache->hashTable[tailHashIndex] = NULL; // 从链表中移除 cache->tail = tailNode->prev; if (cache->tail != NULL) { cache->tail->next = NULL; } else { cache->head = NULL; } free(tailNode); cache->size--; } } // 从缓存中获取值 int get(LRUCache *cache, int key) { int hashIndex = key % MAX_SIZE; Node *node = cache->hashTable[hashIndex]; while (node != NULL) { if (node->key == key) { // 键存在,移动到头部并返回值 moveToHead(cache, node); return node->value; } node = node->next; } // 键不存在 return -1; }
在上面的代码中,定义了LRU缓存的数据结构 LRUCache
,包含一个双向链表(用于跟踪数据的使用顺序)和哈希表(用于快速查找节点)。同时,定义了插入和访问操作。
接下来,示例代码展示了如何使用LRU缓存:
int main() { // 初始化LRU缓存 LRUCache *cache = initLRUCache(); // 插入键值对 put(cache, 1, 100); put(cache, 2, 200); put(cache, 3, 300); // 获取值 printf("获取键1的值:%d\n", get(cache, 1)); // 输出100 printf("获取键2的值:%d\n", get(cache, 2)); // 输出200 printf("获取键3的值:%d\n", get(cache, 3)); // 输出300 // 插入新键值对,会淘汰最久未使用的键2 put(cache, 4, 400); // 获取值 printf("获取键1的值:%d\n", get(cache, 1)); // 输出100 printf("获取键2的值:%d\n", get(cache, 2)); // 输出-1(键2被淘汰) printf("获取键3的值:%d\n", get(cache, 3)); // 输出300 printf("获取键4的值:%d\n", get(cache, 4)); // 输出400 // 释放LRU缓存 freeLRUCache(cache); return 0; }
在上面的代码中,我们首先初始化一个LRU缓存,然后插入键值对 (1, 100)
、(2, 200)
和 (3, 300)
。接着,通过调用 get()
函数获取这些键的值。在插入新键值对 (4, 400)
后,最久未使用的键 (2, 200)
被淘汰。因此,再次获取键 2
的值时,将返回 -1
。
LRU缓存是一种基于双向链表和哈希表的数据结构,用于管理缓存中的数据并自动淘汰最近最少使用的数据。它通过高效的插入、访问和删除操作,提高了应用程序的性能。LRU缓存非常适合用于对数据访问频率较高且具有较强时效性的数据集。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。