C++实现LRU页面置换算法(最近最久未使用)

实现LRU算法

//真正用于存放数据的结构——双向链表
class myListNode{
public:
    int key;
    int val;
    myListNode* pre;
    myListNode* next;
    myListNode() : key(0),val(0),pre(nullptr),next(nullptr) {}
    myListNode(int _key,int _val) : key(_key),val(_val),pre(nullptr),next(nullptr) {}
};

class LRUCache {
private:
	//哈希表,存放key和对应节点地址
    unordered_map<int,myListNode*> hash;
    //链表的头和尾
    myListNode* head;
    myListNode* tail;
    //容量
    int capacity;
    //已经存放的数据量
    int size;
public:
	//构造函数
    LRUCache(int _capacity) : capacity(_capacity),size(0) {
        head = new myListNode();
        tail = new myListNode();
        head->next = tail;
        tail->pre = head;
    }
    //访问数据
    int get(int key) {
        auto it = hash.find(key);
        //如果不存在返回-1
        if(it == hash.end()) return -1;
        //存在则调整页面使用历史,并返回值
        else {
        	//取出该节点
            myListNode* currentNode = hash[key];
            //在链表中删去此节点
            RemoveNode(currentNode);
            //把此节点放到头节点之后,即调整该节点为最近使用的节点
            AddToHead(currentNode);
            return currentNode->val;
        }
    }
    //存放数据
    void put(int key, int value) {
        auto it = hash.find(key);
        //如果没有这个节点
        if(it == hash.end()) {
        	//新键节点,并放至开头
            myListNode* currentNode = new myListNode(key,value);
            AddToHead(currentNode);
            //更新哈希表和size
            hash.insert(make_pair(key,currentNode));
            size++;
            //如果超出容量,则把节点尾部,也就是最久未使用的删除
            if(size > capacity) {
                RemoveTail();
                size--;
            }
        }
        //如果有这个节点,修改值并调整使用历史
        else {
            myListNode* currentNode = hash[key];
            currentNode->val = value;
            RemoveNode(currentNode);
            AddToHead(currentNode);
        }
    }
    //删除节点
    void RemoveNode(myListNode* currentNode) {
    	//后一个节点的pre,指向该节点的前一个节点
        currentNode->next->pre = currentNode->pre;
        //前一个节点的next,指向该节点的后一个节点
        currentNode->pre->next = currentNode->next;
        //该节点的前后指针置空
        currentNode->next = nullptr;
        currentNode->pre = nullptr;
    }
    //将节点添加至头
    void AddToHead(myListNode* currentNode) {
        head->next->pre = currentNode;
        currentNode->next = head->next;
        head->next = currentNode;
        currentNode->pre = head;
    }
    //删除最久未使用的节点
    void RemoveTail(){
        myListNode* currentNode = tail->pre;
        currentNode->pre->next = tail;
        tail->pre = currentNode->pre;
        hash.erase(currentNode->key);
        delete currentNode;
        currentNode = nullptr;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值