面试经典题 手撸LRU

1.C与C++混搭写法

struct LRUCacheNode {
    int key;   
    int value;
    LRUCacheNode* prev; 
    LRUCacheNode* next;
    LRUCacheNode():key(0),value(0),prev(NULL),next(NULL){}
};

class Cache{

public:
    Cache(int cap){
        this->capacity = cap;
        this->count = 0;
        head = new LRUCacheNode;
        tail = new LRUCacheNode;
        head->prev = NULL;
        head->next = tail;
        tail->prev = head;
        tail->next = NULL;
    }
    int get( int key)
    {
        if(m.find(key) == m.end())  // 没找到
            return NULL;
        else
        {
            LRUCacheNode* node = m[key];
            detachNode(node);      // 命中,移至头部
            insertToFront(node);
            return node->value;
        }
    }
    void set( int key, int value)
    {
        LRUCacheNode* node = new LRUCacheNode;
        if(count == capacity)   // Cache已满
        {
            printf("cache is full,delete lrunode\n");
            removeLRUNode();
        }
        node->key = key;
        node->value = value;
        m[key] = node;         // 插入哈希表
        insertToFront(node);    // 插入链表头部
        ++count;
    }

private:
    
    std::unordered_map< int, LRUCacheNode*> m;  // 代替hash_map
    LRUCacheNode* head;     // 指向双链表的头结点
    LRUCacheNode* tail;     // 指向双链表的尾结点
    int capacity;           // Cache的容量
    int count;              // 计数
    void removeLRUNode()                 // 删除尾结点(最久未使用)
    {
        LRUCacheNode* node = tail->prev;
        detachNode(node);
        m.erase(node->key);
        --count;
    }
    void detachNode(LRUCacheNode* node)    // 分离当前结点
    {
        node->prev->next = node->next;
        node->next->prev = node->prev;
    }
    void insertToFront(LRUCacheNode* node) // 节点插入到头部
    {
        node->next = head->next;
        node->prev = head;
        head->next = node;
        node->next->prev = node;
    }
      
    
};

 

2.纯C++写法 

#include 
#include 
#include 
#include 
using namespace std;
using namespace stdext;

class LRUCache {
public:
    LRUCache(int capacity) {
        m_capacity = capacity;
    }

    int get(int key) {
        int retValue = -1;
        unordered_map > ::iterator> ::iterator it = cachesMap.find(key);

        //如果在Cashe中,将记录移动到链表的最前端
        if (it != cachesMap.end())
        {
            retValue = it->second->second;
            //移动到最前端
            list > ::iterator ptrPair = it->second;
            pair tmpPair = *ptrPair;
            caches.erase(ptrPair++);
            caches.push_front(tmpPair);


            //修改map中的值
            cachesMap[key] = caches.begin();
        }
        return retValue;
    }

    void set(int key, int value) {

        unordered_map > ::iterator> ::iterator it = cachesMap.find(key);

        if (it != cachesMap.end()) //已经存在其中
        {
            list > ::iterator ptrPait = it->second;
            ptrPait->second = value;
            //移动到最前面
            pair tmpPair = *ptrPait;
            caches.erase(ptrPait);
            caches.push_front(tmpPair);


            //更新map
            cachesMap[key] = caches.begin();
        }
        else //不存在其中
        {
            pair tmpPair = make_pair(key, value);


            if (m_capacity == caches.size()) //已经满
            {
                int delKey = caches.back().first;
                caches.pop_back(); //删除最后一个


                                   //删除在map中的相应项
                unordered_map > ::iterator> ::iterator delIt = cachesMap.find(delKey);
                cachesMap.erase(delIt++);
            }


            caches.push_front(tmpPair);
            cachesMap[key] = caches.begin(); //更新map
        }
    }


private:
    int m_capacity;                                                                        //cashe的大小
    list > caches;                                                  //用一个双链表存储cashe的内容
    unordered_map< int, list > ::iterator> cachesMap;         //使用map加快查找的速度
};


int main(int argc, char **argv)
{
    LRUCache s(2);
    s.set(2, 1);
    s.set(1, 1);
    cout << s.get(2) << endl;
    s.set(4, 1);
    s.set(5, 2);
    cout << s.get(5) << endl;
    cout << s.get(4) << endl;
    getchar();
    return 0;
}

 

你可能感兴趣的:(算法)