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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM