LFU缓存实现

LFU缓存实现
 
struct LFUObject {
    int freq;
    int key;
    int value;
    LFUObject* next;
    LFUObject* prev;
    LFUObject() {
        freq = 0;
        key = 0;
        value = 0;
        next = NULL;
        prev = NULL;
    }
};

struct FreqObject {
    LFUObject* head;
    LFUObject* tail;
    FreqObject() {
        head = new LFUObject();
        tail = new LFUObject();
        head->next = tail;
        tail->prev = head;
    }
    ~FreqObject() {
        delete head;
        delete tail;
    }
};

class LFUCache {
private:
    unordered_map<int, FreqObject*> freq_list;
    unordered_map<int, LFUObject*> cache_list;
    int capacity;
    int min_freq;
    void remove(LFUObject* node) {
        node->prev->next = node->next;
        node->next->prev = node->prev;
        // clean if no object and update min_freq
        FreqObject* tmp = freq_list[node->freq];
        if (tmp->head->next == tmp->tail) {
            freq_list.erase(node->freq);
            // if update node, min_freq++, if insert node, min_freq = 1
            // min_freq++ alwasy > 1
            if (this->min_freq == node->freq) {
                this->min_freq++;
            }
            delete tmp;
        }
    }
    void insert(LFUObject* node) {
        // each time to update min_freq
        if (freq_list.find(node->freq) == freq_list.end()) {
            freq_list[node->freq] = new FreqObject();
            this->min_freq = min(this->min_freq, node->freq);
        }
        FreqObject* tmp = freq_list[node->freq];
        node->next = tmp->head->next;
        node->prev = tmp->head;
        tmp->head->next = node;
        node->next->prev = node;
    }
public:
    /*
    * @param capacity: An integer
    */LFUCache(int capacity) {
        // do intialization if necessary
        this->capacity = capacity;
        this->min_freq = INT_MAX;
    }

    /*
     * @param key: An integer
     * @param value: An integer
     * @return: nothing
     */
    void set(int key, int value) {
        // write your code here
        if (cache_list.find(key) == cache_list.end()) {
            if (cache_list.size() == this->capacity) {
                LFUObject* tmp = freq_list[this->min_freq]->tail->prev;
                remove(tmp);
                cache_list.erase(tmp->key);
                delete tmp;
            }
            LFUObject* new_lfu = new LFUObject();
            new_lfu->key = key;
            new_lfu->value = value;
            new_lfu->freq = 1;
            insert(new_lfu);
            cache_list[key] = new_lfu;
        } else {
            LFUObject* tmp = cache_list[key];
            tmp->value = value;
            remove(tmp);
            tmp->freq++;
            insert(tmp);
        }
    }

    /*
     * @param key: An integer
     * @return: An integer
     */
    int get(int key) {
        // write your code 
        if (cache_list.find(key) != cache_list.end()) {
            LFUObject* tmp = cache_list[key];
            remove(tmp);
            tmp->freq++;
            insert(tmp);
            return tmp->value;
        }
        return -1;
    }
};

second time to implement

struct LFUCacheNode {
    int key;
    int value;
    int visit;
    LFUCacheNode *prev;
    LFUCacheNode *next;
    LFUCacheNode(int k):key(k), value(0), visit(0), prev(NULL), next(NULL){}
};
struct LFUCacheVisit {
    int visit;
    LFUCacheNode *head;
    LFUCacheNode *tail;
    LFUCacheVisit(int v) {
        visit = v;
        head = new LFUCacheNode(0);
        tail = new LFUCacheNode(0);
        head->next = tail;
        tail->prev = head;
    }
    ~LFUCacheVisit() {
        delete head;
        delete tail;
    }
};

class LFUCache {
public:
    /*
    * @param capacity: An integer
    */LFUCache(int capacity) {
        // do intialization if necessary
        this->capacity = capacity;
        minvisit = 1;
    }

    /*
     * @param key: An integer
     * @param value: An integer
     * @return: nothing
     */
    void set(int key, int value) {
        // write your code here
        if (nodemaps.find(key) == nodemaps.end()) {
            if (nodemaps.size() >= capacity) {
                LFUCacheNode *node = visitmaps[minvisit]->tail->prev;
                nodemaps.erase(node->key);
                deletenode(node);
                delete node;
            }
            nodemaps[key] = new LFUCacheNode(key);
        } else {
            deletenode(nodemaps[key]);
        }
        nodemaps[key]->value = value;
        addnode(nodemaps[key]);
    }

    /*
     * @param key: An integer
     * @return: An integer
     */
    int get(int key) {
        // write your code here
        if (nodemaps.find(key) == nodemaps.end()) {
            return -1;
        } else {
            LFUCacheNode *tmp = nodemaps[key];
            deletenode(tmp);
            addnode(tmp);
            return tmp->value;
        }
    }
private:
    void deletenode(LFUCacheNode *node) {
        node->next->prev = node->prev;
        node->prev->next = node->next;
        // empty()
        LFUCacheVisit *tmp = visitmaps[node->visit];
        if (tmp->head->next == tmp->tail) {
            visitmaps.erase(tmp->visit);
            if (minvisit == tmp->visit) {
                minvisit++;
            }
            delete tmp;
        }
    }
    void addnode(LFUCacheNode *node) {
        node->visit++;
        if (node->visit < minvisit) {
            minvisit = node->visit;
        }
        if (visitmaps.find(node->visit) == visitmaps.end()) {
            visitmaps[node->visit] = new LFUCacheVisit(node->visit);
        }
        LFUCacheVisit *tmp = visitmaps[node->visit];
        node->next = tmp->head->next;
        tmp->head->next = node;
        node->next->prev = node;
        node->prev = tmp->head;
    }
    int capacity;
    unordered_map<int, LFUCacheNode*> nodemaps;
    unordered_map<int, LFUCacheVisit*> visitmaps;
    int minvisit;
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值