LRU算法

1. 定义:
      LRU算法,也就是最近最少使用算法,是一种用于操作系统缺页置换的算法,大概的思想是:操作系统维护一个页面单链表,新进入的页面和链表中被访问的页面移到链表头,链表满需要置换时从链表尾移除页面
 
2. 程序代码:
      实现LRU算法,维护一张链表,将新来的节点、访问到的节点都插入到链表的头部,如果链表长度超过容量,则移除尾部的节点。代码如下:
#include <iostream>
using namespace std;
class LRUCache
{
public:
    LRUCache(int capacity)
    {
        LRUlist_Len = capacity;    
        cnt = 0;
        head = NULL;
    }

/*查找key,若存在返回key对应的value,否则返回-1*/
    int get(int key)
    {
        ListNode *cur = head;
        ListNode *precur = NULL;
        while(cur)
        {
            if(cur->kv.first == key) //找到之后,将找到的页放到链表头
            {
                cout<<cur->kv.first<<" -> "<<cur->kv.second<<endl;
                if(precur != NULL)
                {
                    precur->next = cur->next;
                    cur->next = head;
                    head = cur;
                    return cur->kv.second;
                }
                else
                {
                    return cur->kv.second;
                }
            }
            precur = cur;
            cur = cur->next;
        }
        cout<<"the key "<<key<<" is not in the LRU list"<<endl;
        return -1;
    }
/*插入(key,value)节点,若已存在key则把该节点移到链表头,否则插入该节点到链表头*/
    void set(int key, int value)
    {
        if(head == NULL)
        {
            head = new ListNode(key,value);
            cnt++;
        }
        else
        {
            ListNode *tmp = head;
            ListNode *pretmp = NULL;
            bool key_flag = false;
            while(tmp)
            {
             //在链表中找到key,则修改key对应的value值,并将该页移动到链表头    
                if(tmp->kv.first == key)   
                {
                    tmp->kv.second = value;
                    if(pretmp != NULL)
                    {
                        pretmp->next = tmp->next;
                        tmp->next = head;
                        head = tmp;
                    }
                    key_flag = true;
                    break;
                }
                pretmp = tmp;
                tmp = tmp->next;
            }
            if(!key_flag)     //key还没有在缓存链表中,需要添加
            {
                if(cnt < LRUlist_Len)  //缓存未达到上限,将插入的新页放到链表头
                {
                    ListNode *newhead = new ListNode(key,value);
                    newhead->next = head;
                    head = newhead;
                    cnt++;
                }
                else        //缓存已到上限,移除链表尾的页,将新页放到链表头
                {
                    ListNode *cur = head;
                    ListNode *precur = NULL;
                    while(cur->next)
                    {
                        precur = cur;
                        cur = cur->next;
                    }
                    if(precur != NULL) //precur不等于NULL,表明链表有多个节点
                    {
                        ListNode *newhead = new ListNode(key,value);
                        newhead->next = head;
                        head = newhead;
                        precur->next = NULL;
                        delete cur;
                        cur = NULL;
                    }
                    else    //precur等于NULL,表明链表只有一个节点
                    {
                        ListNode *newhead = new ListNode(key,value);
                        newhead->next = NULL;
                        delete head;
                        head = newhead;
                    }
                }
            }
        }
    }
privateint LRUlist_Len;
    int cnt;
    struct ListNode
    {
        pair<int,int> kv;
        ListNode *next;
        ListNode(int key, int value)
        {
            kv.first = key;
            kv.second = value;
            next = NULL;
        }
    };
    ListNode *head;
};

int main()
{
    LRUCache lc(5);
    lc.set(3,5);
    lc.set(6,188);
    lc.set(1,10);
    lc.set(8,1);
    lc.set(2,9);
    lc.set(1,5);
    lc.get(2);    
    lc.set(4,17);
    lc.get(3);  
    lc.get(1);
    return 0;  
}
    运行结果如下:

 

posted @ 2018-03-27 11:29  IvanB.G.Liu  阅读(457)  评论(0编辑  收藏  举报