LRUCache

来源:互联网 发布:怎么知道我的网络 编辑:程序博客网 时间:2024/06/06 04:28

LRUCache往往用于排列最近被”修改或访问过的热门的“数据,属缓存类目,是我个人认为链表系中,和跳表共同组成链表系的两个最大的实体


其组成,就是一个双向链表,同时有一个hash表实现快速的由key找到对应节点,当有读取操作时,如果能够找到对应key的节点,不仅符合节点value,还会把该key对应节点放在链表头部位置,当修改或插入操作时,如hash表可以找到该key的节点即update,并不是仅更新value这样,而是先删除该节点,然后创建一个新的节点并放在头部,插入也是会将新创建的节点作为链表头,体现了最新被操作的key的数据总是被更新在链表头部。


LRUCache自定义链表的容量限制,当插入新节点时发现已满,则要删除尾部节点,再创建新节点并置于头部,意味着代码需要维护tail节点。

LRUCache往往实践中被用于缓存,是一个重要的数据结构。


代码:

#include <iostream>#include <unordered_map>template<class T> struct Node {    T key;    T val;    Node<T> *next;    Node<T> *prev;    Node(T _key, T _val):key(_key), val(_val), next(nullptr), prev(nullptr) {}};template<class T> class LruCache {    Node<T> *head;    Node<T> *tail;    int size;    int maxsize;    std::unordered_map<T, Node<T> *> nodemap;    void Insert (T key, T val) {        Node<T> *newnode = new Node<T>(key, val);        if (!head) {            head = newnode;            tail = newnode;            head->next = tail->next = nullptr;            head->prev = tail->prev = nullptr;            return;        }        newnode->next = head;        newnode->prev = head->prev;        head->prev = newnode;        head = newnode;        nodemap[key] = newnode;    }    void Delete (Node<T> *node) {        if (node) {            Node<T> *prev = node->prev;            Node<T> *next = node->next;            if (prev) {                prev->next = next;            }            if (next) {                next->prev = prev;            }            if (node == tail) {                tail = prev;            }            nodemap.erase(node->key);            delete node;            node = nullptr;        }    }    public:    LruCache (int _maxsize):size(0), maxsize(_maxsize), head(nullptr), tail(nullptr) {}    ~LruCache () {        Node<T> *cur = head;        while (cur) {            Node<T> *next = cur->next;            delete cur;            cur = next;        }        size = 0;        nodemap.clear();    }    void Set (T key, T val) {        if (nodemap.find(key) == nodemap.end()) {            if (size < maxsize) {                Insert(key, val);                ++size;            } else {                Delete(tail);                Insert(key, val);            }        } else {            Node<T> *node = nodemap.find(key)->second;            Delete(node);            Insert(key, val);        }    }    bool Get (T key, T &val) {        if (nodemap.find(key) != nodemap.end()) {            Node<T> *node = nodemap.find(key)->second;            val = node->val;            Delete(node);            Insert(key, val);            return true;        }        return false;    }    void Show () {        Node<T> *cur = head;        while (cur) {            std::cout << cur->key << "\t";            cur = cur->next;        }        std::cout << std::endl;    }};int main () {    LruCache<int> lrc(20);    for (int i = 0; i < 100; i++) {        lrc.Set(i, i);        lrc.Show();        int v;        lrc.Get(i - 1, v);        lrc.Show();    }    return 0;}


原创粉丝点击