LRU算法 C++实现

来源:互联网 发布:网络犯罪的客观原因有 编辑:程序博客网 时间:2024/06/01 19:24

整体思路:一个循环队列同时使用节点的计数来标记节点的新旧信息,如果有新节点加入时,就把最旧的节点清空,将新节点加入。具体画一下图比较好理解。

#include <iostream>#include <vector>#include <map>#include <queue>using namespace std;static const int LEN = 5;int main(){    vector<int> vires(LEN,-1);//保存结果    vector<int> vi(LEN,-1);//循环数组    deque<int> empty;//上层为空的结点在结果数组中的下标    map<int,int> mii,miires;//mii记录vi里的点的计数,miires记录的是点在vires里的下标    for(int i=0;i<LEN;++i){        empty.push_back(i);    }    int itp,ict=0;    while(cin>>itp){        if(mii.count(vi[ict])){//如果存在,删除循环队列中原来的数            --mii[vi[ict]];            if(mii[vi[ict]]==0){                empty.push_back(miires[vi[ict]]);                mii.erase(mii.find(vi[ict]));            }        }        vi[ict]=itp;//给循环队列中当前位置赋新值        mii[itp]+=1;        ++ict;        ict%=LEN;        if(miires.count(itp)){            auto atp = empty.begin();            for(;atp!=empty.end();++atp){                if(*atp==miires[itp]) break;            }            if(*atp == miires[itp]) empty.erase(atp);        }        else{//真实存储中没有这个数,需要存进去            if(vires[empty.front()]!=-1) miires.erase(miires.find(vires[empty.front()]));            vires[empty.front()]=itp;            miires[itp]=empty.front();            empty.pop_front();            //print            for(auto ieh:vires){                if(ieh!=-1)                    cout<<ieh<<" ";            }            cout<<endl;        }    }    return 0;}//1 2 3 4 5 6 5 4 3 1 7 9 1 2 3 5 6 9 4 2 1

结果如下:

1 2 3 4 5 6 5 4 3 1 7 9 1 2 3 5 6 9 4 2 11 1 2 1 2 3 1 2 3 4 1 2 3 4 5 6 2 3 4 5 6 1 3 4 5 7 1 3 4 5 7 1 3 4 9 7 1 3 2 9 5 1 3 2 9 5 1 3 2 6 5 9 3 2 6 5 9 3 4 6 5 9 2 4 6 1 9 2 4 6 

这个实现中有些地方需要在数组中查找元素,效率差就差在这里,如果需要时间复杂度为O(1)的插入与删除,还是得用hashMap+双向链表。




原创粉丝点击