146. LRU Cache

/*

数据结构: 

1. 一个map,key是key,value是这个元素的指针。用指针是为了快速定位到下面的双向链表中,如果没有,就需要遍历双向链表,导致查找效率低下。

2. 一个双向链表,所有的元素都在这个双向链表中,每次访问元素

    a) 用key得到这个元素的指针

    b)根据指针从双向链表中摘下来,

    c)然后插入到这个双向链表的表头(链表头是最新访问的节点)

3. 插入一个元素

    如果容量超过capacity

        a) 把双向链表的队尾元素摘下来,然后删除(淘汰掉最老的元素)

        b)把新元素插入到双向链表的表头。

为什么用map,

        根据key,很快能找到相应的元素

为什么用双向链表,

        摘除元素,插入到链表头部,都很简单,修改几个指针就行了。

*/

// Acception of mine Jacob
typedef struct my_val my_val_t;
struct my_val {
int key;
int val;
my_val_t* pre;
my_val_t* next;
my_val(int v) { val = v;pre = NULL; next = NULL; };
my_val(int key, int v) { key = key;val = v;pre = NULL; next = NULL; };
};


class LRUCache {
public:
LRUCache(int capacity) {
m_capacity = capacity;
m_node = (my_val_t*)malloc(sizeof(my_val_t));
m_node->pre = m_node;
m_node->next = m_node;
}


int get(int key) {
if (m_data.count(key))
{
my_val_t* p = m_data[key];
int ans = p->val;


getoffNode(p);
insertNodeTofirst(p);


return ans;
}
else
{
return -1;
}
}


void put(int key, int value) {
//set
if (m_data.count(key))
{
my_val_t* p = m_data[key];
p->val = value;


getoffNode(p);
insertNodeTofirst(p);


}
//insert
else
{
my_val_t* p = (my_val_t*)malloc(sizeof(my_val_t));
p->val = value;
p->key = key;


if (m_data.size() >= m_capacity)
{
//delete the last node
my_val_t* qLast = m_node->pre;
getoffNode(qLast);


int key = qLast->key;
m_data.erase(key);

free(qLast);
qLast->pre = NULL;
qLast->next = NULL;
qLast = NULL;

//insert the new node to the first                
insertNodeTofirst(p);
}
else
{
//insert the new node to the first double queue
insertNodeTofirst(p);
}


// insert into map
m_data[key] = p;


}
};


private:


void getoffNode(my_val_t* p)
{
p->pre->next = p->next;
p->next->pre = p->pre;
};
void insertNodeTofirst(my_val_t* p)
{
p->next = m_node->next;
m_node->next->pre = p;
m_node->next = p;
p->pre = m_node;
}
map<int, my_val_t*> m_data;
my_val_t* m_node;
int         m_capacity;
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值