zoukankan      html  css  js  c++  java
  • LRU (近期最少使用)算法 c++实现

    前言

    这两天碰到面试题,说是页面调度算法,之前在操作系统书上有了解过,LRU(近期最少使用),还有OPT(最佳页面替换算法)、FIFO(先进先出页面置换算法),今天先来实现LRU 最近最少使用。

    LRU 原理

    LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。

    参照网上的写法,给出以下例子做个参考:

     1 #include <iostream>
     2 #include <unordered_map>  
     3 #include <list>  
     4 #include <utility>  
     5 using namespace std;
     6 using namespace stdext;
     7 
     8 class LRUCache {
     9 public:
    10     LRUCache(int capacity) {
    11         m_capacity = capacity;
    12     }
    13 
    14     int get(int key) {
    15         int retValue = -1;
    16         unordered_map<int, list<pair<int, int> > ::iterator> ::iterator it = cachesMap.find(key);
    17 
    18         //如果在Cashe中,将记录移动到链表的最前端  
    19         if (it != cachesMap.end())
    20         {
    21             retValue = it->second->second;
    22             //移动到最前端  
    23             list<pair<int, int> > ::iterator ptrPair = it->second;
    24             pair<int, int> tmpPair = *ptrPair;
    25             caches.erase(ptrPair++);
    26             caches.push_front(tmpPair);
    27 
    28 
    29             //修改map中的值  
    30             cachesMap[key] = caches.begin();
    31         }
    32         return retValue;
    33     }
    34 
    35     void set(int key, int value) {
    36 
    37         unordered_map<int, list<pair<int, int> > ::iterator> ::iterator it = cachesMap.find(key);
    38 
    39         if (it != cachesMap.end()) //已经存在其中  
    40         {
    41             list<pair<int, int> > ::iterator ptrPait = it->second;
    42             ptrPait->second = value;
    43             //移动到最前面  
    44             pair<int, int > tmpPair = *ptrPait;
    45             caches.erase(ptrPait);
    46             caches.push_front(tmpPair);
    47 
    48 
    49             //更新map  
    50             cachesMap[key] = caches.begin();
    51         }
    52         else //不存在其中  
    53         {
    54             pair<int, int > tmpPair = make_pair(key, value);
    55 
    56 
    57             if (m_capacity == caches.size()) //已经满  
    58             {
    59                 int delKey = caches.back().first;
    60                 caches.pop_back(); //删除最后一个  
    61 
    62 
    63                                    //删除在map中的相应项  
    64                 unordered_map<int, list<pair<int, int> > ::iterator> ::iterator delIt = cachesMap.find(delKey);
    65                 cachesMap.erase(delIt++);
    66             }
    67 
    68 
    69             caches.push_front(tmpPair);
    70             cachesMap[key] = caches.begin(); //更新map  
    71         }
    72     }
    73 
    74 
    75 private:
    76     int m_capacity;                                                                        //cashe的大小  
    77     list<pair<int, int> > caches;                                                  //用一个双链表存储cashe的内容  
    78     unordered_map< int, list<pair<int, int> > ::iterator> cachesMap;         //使用map加快查找的速度  
    79 };
    80 
    81 
    82 int main(int argc, char **argv)
    83 {
    84     LRUCache s(2);
    85     s.set(2, 1);
    86     s.set(1, 1);
    87     cout << s.get(2) << endl;
    88     s.set(4, 1);
    89     s.set(5, 2);
    90     cout << s.get(5) << endl;
    91     cout << s.get(4) << endl;
    92     getchar();
    93     return 0;
    94 }

    在vs 2015 进行运行 ,输出:

    解释:程序首先会初始化2个存储空间的LRUCache类,依次插进{2, 1 },{1,1} ,之后输出 key=2 => value=1 ,之后插进 {4, 1} , 因为已经满了所以替换掉最近没有使用的{1 ,1} ,变成了 { 4,1} ,{2,1} ,之后又插进{5, 2} ,又替换掉了 {2,1} ,变成了 {4, 1} ,{5,2},然后输出剩下两个key,再重新排序谁最近使用过。

    用到的知识是 : 双链表 + 哈希表 (使用map,内部元素自动排序;使用unordered_map内部不会进行有序排序)

    页面调度算法(LRU)的原理 :缓存机制中新数据或击中的数据放到链表头部,表示最近使用的数据,如果链表满,从尾部淘汰数据。但只用链表会存在一个问题,击中数据的时间复杂度为O(n),每次需要遍历链表,所以引入哈希表,时间复杂度降到O(1),以空间换时间。

  • 相关阅读:
    二叉排序树
    C# 大端与小端
    【转】C#socket通信
    【转】Github 搜索技巧,快速找到好资源
    web api 跨域请求,ajax跨域调用webapi
    【转】Linux简介及最常用命令
    【转】带你吃透RTMP
    09-vuex基本应用之计数demo
    08-配置vue路由的步骤
    02-原型与原型链
  • 原文地址:https://www.cnblogs.com/Hwangzhiyoung/p/9305786.html
Copyright © 2011-2022 走看看