现在的位置: 首页 > 综合 > 正文

LRU cache的一个简单实现

2018年02月20日 ⁄ 综合 ⁄ 共 1748字 ⁄ 字号 评论关闭

用一个结构表示Key 和 Value:

class LRUCacheNode
{
friend LRUCache;
int mKey, mVal;
LRUCacheNode* next;
LRUCacheNode* pre;
LRUCacheNode(int iK, int iV):mKey(iK), mVal(iV), next(NULL), pre(NULL){};
};

用map 或 hash表示<key, LRUCacheNode*>,  用于快速查找key对应的value。

用一个LRUCacheNode 组成的双向链表来维护key和value的访问先后顺序.

实现set和get的时间复杂度都是O(1).

代码如下:

class LRUCache{

	class LRUCacheNode
	{
		friend LRUCache;
		int mKey, mVal;
		LRUCacheNode* next;
		LRUCacheNode* pre;
		LRUCacheNode(int iK, int iV):mKey(iK), mVal(iV), next(NULL), pre(NULL){};
	};
	
	//use map or unorder_map provde the quick check the value of the key.
	map<int/*key*/, LRUCacheNode*> mKeyMap;

	//use the dinay list to matain the squence of the visit time.
	LRUCacheNode head;
	LRUCacheNode tail;

	int mC;
	int mNum;
public:
	LRUCache(int capacity):head(LRUCacheNode(-1, -1)),tail(LRUCacheNode(-2, -2)) {
        mC = capacity;
		mNum = 0;
		mKeyMap.clear();
		
		head.next = &tail;
		tail.pre = &head;
    }
    
    int get(int key) {
		if(mKeyMap.find(key) == mKeyMap.end())
		{
			return -1;
		}
		else
		{
			LRUCacheNode* lNode = mKeyMap[key];
			hDeleteNodeFromDequeue(lNode);
			hMoveNodeToHead(lNode);
			return lNode->mVal;
		}
    }
    
    void set(int key, int value) {
		if(mKeyMap.find(key) == mKeyMap.end())
		{
			if(mNum == mC)
			{
				LRUCacheNode* ldeteNode = hRemoveNodeFromTail();
				mKeyMap.erase(ldeteNode->mKey);
				delete ldeteNode;
				mNum --;
			}
			LRUCacheNode* lNode = new LRUCacheNode(key, value);
			hMoveNodeToHead(lNode);
			mKeyMap[key] = lNode;
			mNum++;
		}
		else
		{
			LRUCacheNode* lNode = mKeyMap[key];
			hDeleteNodeFromDequeue(lNode);
			hMoveNodeToHead(lNode);
			lNode->mVal = value;
		}
    }

private:
	void hDeleteNodeFromDequeue(LRUCacheNode* iNode)
	{
		if(iNode == NULL) return;

		iNode->next->pre = iNode->pre;
		iNode->pre->next = iNode->next;
	}

	void hMoveNodeToHead(LRUCacheNode* iNode)
	{
		if(iNode == NULL) return;

		iNode->next = head.next;
		iNode->pre = &head;
		head.next = iNode;
		iNode->next->pre = iNode;
	}

	LRUCacheNode* hRemoveNodeFromTail()
	{
		LRUCacheNode* lDeNode = tail.pre;

		tail.pre = lDeNode->pre;
		lDeNode->pre->next = &tail;
		return lDeNode;
	}

};

抱歉!评论已关闭.