LRU缓存淘汰算法的C++实现【C++模板类】

LRU缓存淘汰算法的C++实现【C++模板类】



前言

算法参考:LeetCode 146.LRU缓存


一、C++模板类实现

采用双向链表+哈希表实现,时间复杂度为O(1)

代码如下:

#pragma once
#include <unordered_map>

/*
 *brief  \双向链表
 *param  \
 */
template <class Key, class Value>
struct DNodeList
{
    Key key;
    Value value;
    DNodeList<Key, Value>* prev = nullptr;
    DNodeList<Key, Value>* next = nullptr;

    DNodeList() {}
    DNodeList(Key k, Value v): key(k), value(v) {}
};

/*
 *brief  \LRU缓存淘汰机制 O(1)复杂度实现(双向链表+哈希表)
 *param  \
 */
template <class Key, class Value>
class LRU
{
public:
    LRU(int capacity): m_capacity(capacity)
    {
        m_head = new DNodeList<Key, Value>();
        m_tail = new DNodeList<Key, Value>();
        m_head->next = m_tail;
        m_tail->prev = m_head;
    }

    ~LRU()
    {
        for (const auto& it : m_map)
        {
            DNodeList<Key, Value>* node = it.second;
            delete node;
        }
        m_map.clear();

        delete m_head;
        delete m_tail;
    }

    // 获取
    bool get(const Key& key, Value& value)
    {
        if (!m_map.count(key))
            return false;
        
        // 访问过后需要移动到头部
        DNodeList<Key, Value>* node = m_map[key];
        moveToHead(node);
        value = node->value;
        return true;
    }

    // 写入
    void put(const Key& key, const Value& value)
    {
        if (m_map.count(key))
        {
            // 存在时移动到头部
            DNodeList<Key, Value>* node = m_map[key];
            node->value = value;
            moveToHead(node);
        }
        else
        {
            // 不存在创建记录
            DNodeList<Key, Value>* node = new DNodeList<Key, Value>(key, value);
            m_map[key] = node;
            addToHead(node);
            ++m_size;

            // 达到最大容量则删除尾部
            if (m_size > m_capacity)
            {
                DNodeList<Key, Value>* removed = removeTail();
                m_map.erase(removed->key);
                delete removed;
                --m_size;
            }
        }
    }

private:
    // 添加到头部
    void addToHead(DNodeList<Key, Value>* node)
    {
        node->prev = m_head;
        node->next = m_head->next;
        m_head->next->prev = node;
        m_head->next = node;
    }

    // 移除节点
    void removeNode(DNodeList<Key, Value>* node)
    {
        node->prev->next = node->next;
        node->next->prev = node->prev;
    }

    // 移动到头节点
    void moveToHead(DNodeList<Key, Value>* node)
    {
        removeNode(node);
        addToHead(node);
    }

    // 删除尾部
    DNodeList<Key, Value>* removeTail()
    {
        DNodeList<Key, Value>* node = m_tail->prev;
        removeNode(node);
        return node;
    }

private:
    int m_size = 0;
    int m_capacity = 0;

    // 头尾节点
    DNodeList<Key, Value>* m_head = nullptr;
    DNodeList<Key, Value>* m_tail = nullptr;

    std::unordered_map<Key, DNodeList<Key, Value>*> m_map;
};

二、使用

代码如下:

#include "LRU.h"
#include <string>

int main(int argc, char* argv[])
{
	// LRU缓存淘汰机制
    LRU<std::string, std::string> lru(10);
    lru.put("pp", "3244");
    
    std::string str;
    if (lru.get("pp", str))
    {
    	// do something
    }
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值