📜  具有双链表的哈希表链接(1)

📅  最后修改于: 2023-12-03 15:22:34.820000             🧑  作者: Mango

具有双链表的哈希表链接

简介

具有双链表的哈希表链接是一种数据结构,同时具有哈希表的查找速度和双链表的插入、删除速度。在实际开发中,常用于缓存、LRU缓存等。

实现方式
哈希表

哈希表是一种以键-值(key-value)作为元素进行存储的数据结构,具有查找速度快的特点。哈希表通过哈希函数对键值进行映射,将键值存储在对应的桶(bucket)中。

常见的哈希函数有取余法、乘法哈希、一致性哈希等。其中取余法是最简单、最常用的哈希函数,它的实现比较简单,适用于键的数量比较稳定的情况。

双链表

双链表是一种链表,它的每个节点都有两个指针:一个指向前一个节点、一个指向后一个节点。双链表具有插入、删除的复杂度为O(1),比单链表的复杂度O(n)要快。

双链表与单链表相比,除了多一个指向前一个节点的指针外,其它都相同。

具有双链表的哈希表链接

将哈希表和双链表结合,可以得到具有双链表的哈希表链接。

在具有双链表的哈希表链接中,每个哈希桶(bucket)都是一个双链表。

在查找元素时,先通过哈希函数找到对应的哈希桶,然后再在哈希桶中进行查找。由于哈希桶是一个双链表,查找起来与普通链表没有区别。

在插入、删除元素时,同样先通过哈希函数找到对应的哈希桶,然后再在哈希桶中进行插入、删除操作。由于哈希桶是一个双链表,插入、删除起来比普通链表更快。

代码示例

下面是一个简单的具有双链表的哈希表链接的代码示例。这里使用了C++语言。

#include <iostream>
#include <unordered_map>
#include <list>

using namespace std;

// 双链表节点
struct Node {
    int key;
    int value;
    Node(int k, int v) : key(k), value(v) {};
};

// 具有双链表的哈希表链接
class LRUCache {
private:
    int capacity;   // 缓存容量
    unordered_map<int, list<Node>::iterator> map;   // 哈希表,存储节点在双链表中的迭代器
    list<Node> cache;   // 双链表
public:
    LRUCache(int cap) : capacity(cap) {};

    // 获取节点
    int get(int key) {
        if(map.find(key) == map.end())
            return -1;
        auto it = map[key];
        Node temp = *it;
        cache.erase(it);
        cache.push_front(temp);
        map[key] = cache.begin();
        return temp.value;
    }

    // 插入节点
    void put(int key, int value) {
        Node node(key, value);
        if(map.find(key) != map.end())
        {
            auto it = map[key];
            cache.erase(it);
        }
        else {
            if(cache.size() >= capacity)
            {
                auto lastNode = cache.back();
                map.erase(lastNode.key);
                cache.pop_back();
            }
        }
        cache.push_front(node);
        map[key] = cache.begin();
    }
};

// 测试
int main() {
    // 缓存容量为2
    LRUCache cache(2);

    // 添加节点
    cache.put(1, 1);
    cache.put(2, 2);
    cout<<cache.get(1)<<endl;  // 1

    // 添加节点
    cache.put(3, 3);
    cout<<cache.get(2)<<endl;  // -1

    // 添加节点
    cache.put(4, 4);
    cout<<cache.get(1)<<endl;  // -1
    cout<<cache.get(3)<<endl;  // 3
    cout<<cache.get(4)<<endl;  // 4

    return 0;
}
总结

具有双链表的哈希表链接是一种高效的数据结构,常用于缓存、LRU缓存等场景。它同时具有哈希表的查找速度和双链表的插入、删除速度,可以在实际开发中发挥重要作用。