最近最少使用置换算法:当缓存满时,移除最近最少使用的数据 算法思路:利用哈希链表的有序性,将数据按最后使用时间排序

    • 使用哈希表存储数据,实现查找和插入数据的时间复杂度都为O(1)
    • 使用双向链表来实现算法逻辑
      • 当数据被访问时,移动该数据到链表头部
      • 缓存满时,删除链表尾部数据

    image.png

    1. #include <iostream>
    2. #include <list>
    3. #include <unordered_map>
    4. using namespace std;
    5. #define PII pair<int, int>
    6. class LRUCache {
    7. public:
    8. LRUCache(int n) : capacity(n) {}
    9. int get(int key) {
    10. /*
    11. 当数据被访问时,将数据移动到链表头部
    12. - 在map中查找,如有,根据it将PII移动到list首部
    13. */
    14. auto it_mp = mp.find(key);
    15. if (it_mp == mp.end()) return -1;
    16. auto it_list = it_mp->second;
    17. // 拷贝被访问的PII到链表头部
    18. PII tmp {it_list->first, it_list->second};
    19. cache.push_front(tmp);
    20. // 删除原有PII,更新map中的it
    21. cache.erase(it_list);
    22. mp.erase(it_mp);
    23. mp.emplace(key, cache.begin());
    24. return tmp.second;
    25. }
    26. int put(int key, int value) {
    27. /*
    28. if原有key -> 删除原有数据,将新数据插入链表头部
    29. if新数据 -> 将数据插入链表头部
    30. - if容量满,删除尾部数据
    31. */
    32. auto it_mp = mp.find(key);
    33. if (it_mp != mp.end()) {
    34. cache.erase(it_mp->second);
    35. mp.erase(it_mp);
    36. }
    37. PII tmp {key, value};
    38. cache.push_front(tmp);
    39. mp.emplace(key, cache.begin());
    40. if (cache.size() > capacity) {
    41. // 先清map中数据
    42. mp.erase(cache.back().first);
    43. cache.pop_back();
    44. }
    45. }
    46. private:
    47. size_t capacity;
    48. /*
    49. 双向链表实现算法逻辑
    50. - 最近访问的数据移动到链表头部
    51. - 缓存满时,删除链表尾部数据
    52. */
    53. list<PII> cache;
    54. // 哈希表存储数据,实现查找和插入效率O(1)
    55. unordered_map<int, list<PII>::iterator> mp;
    56. };
    57. int main() {
    58. LRUCache *lru = new LRUCache(2);
    59. lru->put(1, 1);
    60. lru->put(2, 2);
    61. cout << lru->get(1) << endl;
    62. lru->put(3, 3);
    63. cout << lru->get(2) << endl; // -1
    64. lru->put(4, 4);
    65. cout << lru->get(1) << endl; // -1
    66. cout << lru->get(3) << endl;
    67. cout << lru->get(4) << endl;
    68. delete lru;
    69. return 0;
    70. }