使用双链表的 LRU Cache 实现
给定列表N和数组Arr的预定义大小。任务是使用双链表实现最近最少使用(LRU)算法。
该程序需要两组输入。首先,链表的大小。第二,要在链表中搜索的元素。
例子:
Input: N = 3, Arr = { 1, 2, 3 }
Output:
[0]->[0]->[0]->NULL
[1]->[0]->[0]->NULL
[2]->[1]->[0]->NULL
[3]->[2]->[1]->NULL
Input: N = 5, Arr = { 1, 2, 3, 4, 3, 8 }
Output:
[0]->[0]->[0]->[0]->[0]->NULL
[1]->[0]->[0]->[0]->[0]->NULL
[2]->[1]->[0]->[0]->[0]->NULL
[3]->[2]->[1]->[0]->[0]->NULL
[4]->[3]->[2]->[1]->[0]->NULL
[2]->[4]->[3]->[1]->[0]->NULL
[8]->[2]->[4]->[3]->[1]->NULL
方法:
这个想法是非常基本的,不断在头部插入元素
- 如果列表中不存在该元素,则将其添加到列表的头部
- 如果元素存在于列表中,则将该元素移动到头部并移动列表的剩余元素
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Creating the structure
// for linkedlist
struct doublelinkedlist {
int val;
struct doublelinkedlist* next;
struct doublelinkedlist* prev;
};
// Creating three list for having
// head, a temporarily list and
// a list for tail
struct doublelinkedlist* head;
struct doublelinkedlist* tail;
struct doublelinkedlist* temp;
int status;
// Function to add new node
// in the list
int AddNode(int value)
{
// if head is NULL creating
// the new node and assigning
// to head
if (head == NULL) {
head = (struct doublelinkedlist*)
malloc(sizeof(struct doublelinkedlist));
if (head == NULL) {
cout <<"Unable to allocate space\n";
return -2;
}
head->val = value;
tail = head;
head->prev = NULL;
}
else {
temp = tail;
tail->next = (struct doublelinkedlist*)
malloc(sizeof(struct doublelinkedlist));
if (tail->next == NULL) {
cout <<"Unable to allocate space\n";
return -2;
}
tail->next->val = value;
tail = tail->next;
tail->prev = temp;
}
tail->next = NULL;
return 0;
}
// Function to print
// the linked list
int Display(void)
{
if (head == NULL) {
cout <<"Add a node first\n";
return -2;
}
else {
temp = head;
while (temp != NULL) {
cout <<"[ ]->"<< temp->val;
temp = temp->next;
}
cout <<"NULL\n";
}
return 0;
}
// Function to search the
// elements is already present
// in the list or not
int SearchCache(int value)
{
if (head == NULL) {
cout <<"Add a node first\n";
return -1;
}
// Store head temporarily.
temp = head;
// Traverse Double Linked List.
while (temp != NULL)
{
// If value in list
// matches with given value.
if (temp->val == value)
{
// Shift all values before
// the found value to the right.
while (temp != head) {
temp->val = temp->prev->val;
temp = temp->prev;
}
// Place the found
// value at the head.
head->val = value;
return 0;
}
// Keep iterating the loop.
temp = temp->next;
}
// For new elements.
temp = tail->prev;
// Shift all value to the
// right and over-write
// the last value.
while (temp != NULL) {
temp->next->val = temp->val;
temp = temp->prev;
}
// Place new value at head.
head->val = value;
return 0;
}
// Initializing function
// that will create the
// list with values 0 in it.
int NumberOfNodes(int number)
{
static int i = 0;
for (i = 0; i < number; i += 1) {
status = AddNode(0);
// if status is 0 then
// it will return
if (status < 0) {
cout <<"Could not assign node\n";
return status;
}
}
return 0;
}
// This function will
// remove the linked
// list from the memory.
int FreeCache(int number)
{
struct doublelinkedlist** freeing_ptr
= &head;
static int i = 0;
for (i = 0; i < number; i += 1) {
free(*freeing_ptr);
*freeing_ptr = NULL;
freeing_ptr += 1;
}
return 0;
}
// Function to perform LRU
// operations
void LRUOp(int arr[], int n)
{
// Iterating through the
// elements so that LRU
// operation can take place
for (int i = 0; i < n; ++i) {
SearchCache(arr[i]);
// If the status is -ve
// then return
if (status < 0) {
exit(1);
}
// Printing it every time
status = Display();
}
}
// Driver Code
int main(void)
{
// Pre defining the
// size of the cache
int MEMSIZE = 5;
status = NumberOfNodes(MEMSIZE);
// Number of elements
// to be added in LRU List.
int n = 10;
// The Numbers to be
// added in LRU List.
int arr[] = { 1, 2, 3, 4, 5,
2, 10, 7, 11, 1 };
LRUOp(arr, n);
// Removing the linked
// list from the memory.
FreeCache(MEMSIZE);
return 0;
}
// this code is contributed by shivanisinghss2110
C
// C implementation of the approach
#include
#include
#include
// Creating the structure
// for linkedlist
struct doublelinkedlist {
int val;
struct doublelinkedlist* next;
struct doublelinkedlist* prev;
};
// Creating three list for having
// head, a temporarily list and
// a list for tail
struct doublelinkedlist* head;
struct doublelinkedlist* tail;
struct doublelinkedlist* temp;
int status;
// Function to add new node
// in the list
int AddNode(int value)
{
// if head is NULL creating
// the new node and assigning
// to head
if (head == NULL) {
head = (struct doublelinkedlist*)
malloc(sizeof(struct doublelinkedlist));
if (head == NULL) {
printf("Unable to allocate space\n");
return -2;
}
head->val = value;
tail = head;
head->prev = NULL;
}
else {
temp = tail;
tail->next = (struct doublelinkedlist*)
malloc(sizeof(struct doublelinkedlist));
if (tail->next == NULL) {
printf("Unable to allocate space\n");
return -2;
}
tail->next->val = value;
tail = tail->next;
tail->prev = temp;
}
tail->next = NULL;
return 0;
}
// Function to print
// the linked list
int Display(void)
{
if (head == NULL) {
printf("Add a node first\n");
return -2;
}
else {
temp = head;
while (temp != NULL) {
printf("[%d]->", temp->val);
temp = temp->next;
}
printf("NULL\n");
}
return 0;
}
// Function to search the
// elements is already present
// in the list or not
int SearchCache(int value)
{
if (head == NULL) {
printf("Add a node first\n");
return -1;
}
// Store head temporarily.
temp = head;
// Traverse Double Linked List.
while (temp != NULL)
{
// If value in list
// matches with given value.
if (temp->val == value)
{
// Shift all values before
// the found value to the right.
while (temp != head) {
temp->val = temp->prev->val;
temp = temp->prev;
}
// Place the found
// value at the head.
head->val = value;
return 0;
}
// Keep iterating the loop.
temp = temp->next;
}
// For new elements.
temp = tail->prev;
// Shift all value to the
// right and over-write
// the last value.
while (temp != NULL) {
temp->next->val = temp->val;
temp = temp->prev;
}
// Place new value at head.
head->val = value;
return 0;
}
// Initializing function
// that will create the
// list with values 0 in it.
int NumberOfNodes(int number)
{
static int i = 0;
for (i = 0; i < number; i += 1) {
status = AddNode(0);
// if status is 0 then
// it will return
if (status < 0) {
printf("Could not assign node\n");
return status;
}
}
return 0;
}
// This function will
// remove the linked
// list from the memory.
int FreeCache(int number)
{
struct doublelinkedlist** freeing_ptr
= &head;
static int i = 0;
for (i = 0; i < number; i += 1) {
free(*freeing_ptr);
*freeing_ptr = NULL;
freeing_ptr += 1;
}
return 0;
}
// Function to perform LRU
// operations
void LRUOp(int arr[], int n)
{
// Iterating through the
// elements so that LRU
// operation can take place
for (int i = 0; i < n; ++i) {
SearchCache(arr[i]);
// If the status is -ve
// then return
if (status < 0) {
exit(1);
}
// Printing it every time
status = Display();
}
}
// Driver Code
int main(void)
{
// Pre defining the
// size of the cache
int MEMSIZE = 5;
status = NumberOfNodes(MEMSIZE);
// Number of elements
// to be added in LRU List.
int n = 10;
// The Numbers to be
// added in LRU List.
int arr[] = { 1, 2, 3, 4, 5,
2, 10, 7, 11, 1 };
LRUOp(arr, n);
// Removing the linked
// list from the memory.
FreeCache(MEMSIZE);
return 0;
}
输出:
[1]->[0]->[0]->[0]->[0]->NULL
[2]->[1]->[0]->[0]->[0]->NULL
[3]->[2]->[1]->[0]->[0]->NULL
[4]->[3]->[2]->[1]->[0]->NULL
[5]->[4]->[3]->[2]->[1]->NULL
[2]->[5]->[4]->[3]->[1]->NULL
[10]->[2]->[5]->[4]->[3]->NULL
[7]->[10]->[2]->[5]->[4]->NULL
[11]->[7]->[10]->[2]->[5]->NULL
[1]->[11]->[7]->[10]->[2]->NULL