c_cpp lru,LRU,设计并实现最近最少使用(LRU)缓存的数据结构。它应该支持以下操作:get和set

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp lru,LRU,设计并实现最近最少使用(LRU)缓存的数据结构。它应该支持以下操作:get和set相关的知识,希望对你有一定的参考价值。

// idea: use a hashtable and a double-linked list.
// every time get or set, check the hashtable first. 

// ====================================================================
class LRUCache {
struct Node {
  int key;
  int value;
  Node *prev;
  Node *next;
  Node(int k, int v) : key(k), value(v), prev(NULL), next(NULL) {}
  Node(int k, int v, Node *pre, Node *nxt) :
    key(k), value(v), prev(pre), next(nxt) {}
};
unordered_map<int, Node*> mp; // map key to node in double linked list
int capacity;
Node* head;
Node* tail;

public:
  LRUCache(int cap) {
    capacity = cap;
    mp.clear();
    head = NULL;
    tail = NULL;
  }
  
  int get(int k) {
    if(mp.find(k) == mp.end()) return -1;
    Node *nd = mp[k];
    moveNodeToHead(nd);
    return mp[k]->value;
  }
  
  void set(int k, int v) {
    if(mp.find(k) != mp.end()) { // already in hashtable, then move to front
      moveNodeToHead(mp[k]);
      mp[k]->value = v;
    } else {
      if(capacity == mp.size()) { // already full, then remove the tail
        mp.erase(tail->key);
        removeNode(tail);
      }
      Node *nd = new Node(k, v);
      insertToHead(nd);
      mp[k] = nd;
    }
  }
  
  void insertToHead(Node *n) {
    if(!head) {
      head = n;
      tail = n;
    } else {
      n->next = head;
      head->prev = n;
      head = n;
    }
  }
  
  void removeNode(Node *n) {
    if(n == head) {
      head = head->next;
      if(head) head->prev = NULL;
    }
    else if(n == tail) {
      tail = tail->prev;
      tail->next = NULL;
    }
    else {
      n->prev->next = n->next;
      n->next->prev = n->prev;
    }
  }
  
  void moveNodeToHead(Node *n) {
    if(n == head) return;
    if(n == tail) {
      tail->prev->next = NULL;
      tail = tail->prev;
      n->next = head;
      head->prev = n;
      head = n;
    } else {
      n->next->prev = n->prev;
      n->prev->next = n->next;
      n->next = head;
      head->prev = n;
      head = n;
    }
  }
};






// ===================== use std::list ================================

struct CacheNode {
    int key;
    int value;
    CacheNode(int k, int v) : key(k), value(v) {}
};

class LRUCache {
private:
    list<CacheNode> cacheList;  // gist, use list because list in c++ is double-linked list, and it has the "splice" method!
    unordered_map<int, list<CacheNode>::iterator> hash;
    int size;
public:
    LRUCache(int sz) : size(sz) {}
    
    int get(int key) {
        if(hash.find(key) == hash.end()) return -1;
        else {
            // move current node to front, update hash
            cacheList.splice(cacheList.begin(), cacheList, hash[key]);
            hash[key] = cacheList.begin();
            return hash[key]->value;
        }
    }
    
    void set(int key, int value) {
        // not exist
        if(hash.find(key) == hash.end()) {
            // if list already full, delete tail node
            if(size == cacheList.size()) {
                hash.erase(cacheList.back().key);
                cacheList.pop_back();
            }
            // insert new node to front, add entry in hash
            cacheList.push_front(CacheNode(key, value));
            hash[key] = cacheList.begin();
        } else {
            // update entry in hash, move node to front, update hash
            hash[key]->value = value;
            cacheList.splice(cacheList.begin(), cacheList, hash[key]);
            hash[key] = cacheList.begin();
        }
    }
};

以上是关于c_cpp lru,LRU,设计并实现最近最少使用(LRU)缓存的数据结构。它应该支持以下操作:get和set的主要内容,如果未能解决你的问题,请参考以下文章

最近最少使用算法----LRU Cache

最近最少使用算法----LRU Cache

146 LRU Cache 最近最少使用页面置换算法

LRU算法java实现

LRU算法java实现

LRU(Least Recently Used最近最少使用)的c++实现(顺序表)