LRU的实现(使用list)

首先是LRU的定义,LRU表示最近最少使用,如果数据最近被访问过,那么将来被访问的几率也更高。

所以逻辑应该是每次都要将新被访问的页放到列表头部,如果超过了list长度限制,就将列表尾部的元素踢出去。

 

主要结构,STL中的双向链表结构list。

主要操作有get,表示访问key对应的value,此时要查询双链表,找到key对应value,再将其从list中删除,插入到list的头部。

     set,  表示设置对应的key值为value,此时先找到key对应的元素,将其从list中删除,再插入到list的头部。

这里设置了两个辅助函数remove和setHead,分别负责删除元素和将元素加入到list头部。

 

代码实现如下:

#include <iostream>
#include <list>
#include <iterator>
#include <algorithm>

using namespace std;

class LRUNode
{
    public:
        int key,value;
        LRUNode(int _key,int _value):key(_key),value(_value)
        {
        }
        bool operator==(LRUNode * p)
        {
            return key==p->key;
        }
};

class LRU
{
    public:
        int get(int key);
        void set(int key,int val);
        LRU(int _cap):cap(_cap)
        {
        }
        int cap;//代表存放的最大页数
        void remove(int key);
        void setHead(int key,int val);
        void printLis();
        list<LRUNode *> lis;
};

void LRU::printLis()
{
    list<LRUNode *>::iterator it;
    for(it=lis.begin();it!=lis.end();it++)
    {
        cout<<(*it)->key<<" "<<(*it)->value<<endl;
    }
    cout<<endl;
}

void LRU::remove(int key)
{
    LRUNode * searchNode=new LRUNode(key,0);
    list<LRUNode *>::iterator it=find(lis.begin(),lis.end(),searchNode);
    if(it!=lis.end())
    {
        lis.remove(*it);
    }
}

void LRU::setHead(int key,int val)
{
    lis.push_front(new LRUNode(key,val));
}

int LRU::get(int key)
{
    LRUNode * searchNode=new LRUNode(key,0);
    list<LRUNode *>::iterator it=find(lis.begin(),lis.end(),searchNode);
    if(it!=lis.end())
    {
        remove((*it)->key);
        setHead((*it)->key,(*it)->value);
        return (*it)->value;
    }
    return -1;//表示没有找到
}

void LRU::set(int key,int value)
{
    if(lis.size()>=cap)
    {
        lis.pop_back();
    }
    LRUNode * searchNode=new LRUNode(key,0);
    list<LRUNode *>::iterator it=find(lis.begin(),lis.end(),searchNode);
    if(it!=lis.end())
    {
        remove(key);
        setHead(key,value);
    }
    else
    {
        setHead(key,value);
    }
}



int main()
{
    LRU * lru=new LRU(5);
    lru->set(1,1);
    lru->printLis();
    lru->set(2,2);
    lru->printLis();
    lru->set(3,3);
    lru->printLis();
    lru->set(4,4);
    lru->printLis();
    lru->set(5,5);
    lru->printLis();
    lru->set(6,6);
    lru->printLis();
    lru->set(7,7);
    lru->printLis();
    return 0;
}

运行结果:

1 1

2 2
1 1

3 3
2 2
1 1

4 4
3 3
2 2
1 1

5 5
4 4
3 3
2 2
1 1

6 6
5 5
4 4
3 3
2 2

7 7
6 6
5 5
4 4
3 3

 

转载于:https://www.cnblogs.com/JsonZhangAA/p/11374439.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是使用C语言实现LRU页面置换算法的示例代码: ```c #include <stdio.h> #include <stdlib.h> #define MAXSIZE 5 // 缓存最大大小 #define HIT 1 // 命中 #define MISS 0 // 未命中 // 双向链表节点 typedef struct _node { int key; // 缓存的键 int value; // 缓存的值 struct _node *prev; // 前驱节点指针 struct _node *next; // 后继节点指针 } Node; // 双向链表 typedef struct _list { int count; // 缓存的节点数 Node *head; // 链表头指针 Node *tail; // 链表尾指针 } List; // 缓存结构体 typedef struct _cache { List *list; // 双向链表指针 int size; // 缓存大小 } Cache; // 创建双向链表 List *createList() { List *list = (List *)malloc(sizeof(List)); list->count = 0; list->head = NULL; list->tail = NULL; return list; } // 创建节点 Node *createNode(int key, int value) { Node *node = (Node *)malloc(sizeof(Node)); node->key = key; node->value = value; node->prev = NULL; node->next = NULL; return node; } // 添加节点到链表头部 void addToHead(List *list, Node *node) { if (list->count == 0) { list->head = node; list->tail = node; } else { node->next = list->head; list->head->prev = node; list->head = node; } list->count++; } // 删除节点 void removeNode(List *list, Node *node) { if (list->count == 0) { return; } if (list->count == 1) { list->head = NULL; list->tail = NULL; } else if (node == list->head) { list->head = node->next; list->head->prev = NULL; } else if (node == list->tail) { list->tail = node->prev; list->tail->next = NULL; } else { node->prev->next = node->next; node->next->prev = node->prev; } free(node); list->count--; } // 删除链表尾部节点 void removeTail(List *list) { if (list->count == 0) { return; } Node *node = list->tail; list->tail = node->prev; if (list->count == 1) { list->head = NULL; list->tail = NULL; } else { list->tail->next = NULL; } free(node); list->count--; } // 移动节点到链表头部 void moveToHead(List *list, Node *node) { if (node == list->head) { return; } if (node == list->tail) { list->tail = node->prev; list->tail->next = NULL; } else { node->prev->next = node->next; node->next->prev = node->prev; } node->prev = NULL; node->next = list->head; list->head->prev = node; list->head = node; } // 创建缓存 Cache *createCache(int size) { Cache *cache = (Cache *)malloc(sizeof(Cache)); cache->list = createList(); cache->size = size; return cache; } // 获取缓存值 int get(Cache *cache, int key, int *value) { Node *node = cache->list->head; while (node) { if (node->key == key) { *value = node->value; moveToHead(cache->list, node); return HIT; } node = node->next; } return MISS; } // 设置缓存值 void put(Cache *cache, int key, int value) { Node *node = cache->list->head; while (node) { if (node->key == key) { node->value = value; moveToHead(cache->list, node); return; } node = node->next; } node = createNode(key, value); addToHead(cache->list, node); if (cache->list->count > cache->size) { removeTail(cache->list); } } // 打印缓存 void printCache(Cache *cache) { Node *node = cache->list->head; while (node) { printf("(%d, %d) ", node->key, node->value); node = node->next; } printf("\n"); } int main() { Cache *cache = createCache(MAXSIZE); int value; put(cache, 1, 1); printf("cache: "); printCache(cache); put(cache, 2, 2); printf("cache: "); printCache(cache); put(cache, 3, 3); printf("cache: "); printCache(cache); get(cache, 1, &value); printf("get(1): %d\n", value); printf("cache: "); printCache(cache); put(cache, 4, 4); printf("cache: "); printCache(cache); put(cache, 5, 5); printf("cache: "); printCache(cache); put(cache, 6, 6); printf("cache: "); printCache(cache); get(cache, 3, &value); printf("get(3): %d\n", value); printf("cache: "); printCache(cache); return 0; } ``` 该示例代码实现了一个LRU缓存,支持添加、获取、打印缓存等操作。其中,缓存使用双向链表来实现,每当有新的元素被访问时,将其移动到链表头部,最近最少使用的元素将会被移动到链表尾部,并在缓存达到最大大小时被删除。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值