LRU手写 双向链表+哈希

 1.我们首先想到快速查询 应该使用哈希表 可以做到快速查询 但是没有固定顺序

2.于是想到又固定顺序还要增加复杂度低 就应该用链表 但是删除做不到常数级别 最终选择双向链表

3.我们可以把双向链表和哈希表得键相映射可以取得联系

2.首先我们应该创建出来一个双向链表

struct Dlist{
    int val;
    int key;
    Dlist* pre;
    Dlist* next;
    Dlist():val(0),key(0),pre(nullptr),next(nullptr){};
    Dlist(int val,int key):val(val),key(key),pre(nullptr),next(nullptr){};
};

1.双向链表尾部就是最近最久未使用得数据 表头是最近经常使用的节点

  void moveTohead(Dlist* node) {
         removeNode(node);
         addNode(node);
    }
    void removeNode(Dlist* node) {
         node->next->pre=node->pre;
         node->pre->next=node->next;
    }
    void addNode(Dlist* node) {
       head->next->pre=node;
       node->next=head->next;
       head->next=node;
       node->pre=head;
    }
    Dlist* moveTail() {
        Dlist* temp=tail->pre;
        removeNode(temp);
        return temp;
    }

 3.实现put get

      

struct Dlist{
    int val;
    int key;
    Dlist* pre;
    Dlist* next;
    Dlist():val(0),key(0),pre(nullptr),next(nullptr){};
    Dlist(int val,int key):val(val),key(key),pre(nullptr),next(nullptr){};
};
class LRUCache {
    private:
     unordered_map<int,Dlist*>mp;
     Dlist* head;
     Dlist* tail;
     int sz;
     int capacity;
public:
    LRUCache(int capacity):capacity(capacity),sz(0) {
          head=new Dlist();
          tail=new Dlist();
          head->next=tail;
          tail->pre=head;
    }
    int get(int key) {
        if (!mp.count(key)) {
            return -1;
        }
        // 如果 key 存在,先通过哈希表定位,再移到头部
        Dlist* node = mp[key];
        moveTohead(node);
        return node->val;
    }
    void put(int key, int value) {   
         if(mp.find(key)==mp.end()){
         Dlist* pnew=new Dlist(value,key); 
         mp[key]=pnew;
         addNode(pnew);
         sz++;
         if(sz > capacity) {
             Dlist* temp=moveTail();
             mp.erase(temp->key);
             delete temp;
             sz--;
          }
         }else {
              mp[key]->val=value;
              moveTohead(mp[key]);
         }
    }
    void moveTohead(Dlist* node) {
         removeNode(node);
         addNode(node);
    }
    void removeNode(Dlist* node) {
         node->next->pre=node->pre;
         node->pre->next=node->next;
    }
    void addNode(Dlist* node) {
       head->next->pre=node;
       node->next=head->next;
       head->next=node;
       node->pre=head;
    }
    Dlist* moveTail() {
        Dlist* temp=tail->pre;
        removeNode(temp);
        return temp;
    }
};

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache* obj = new LRUCache(capacity);
 * int param_1 = obj->get(key);
 * obj->put(key,value);
 */

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值