小工具知识网

当前位置: 首页 > 行业知识 > 【C++】unordered

行业知识

【C++】unordered

2026-11-10 02:24:43 来源:互联网转载

文章目录

  • 1. 哈希表的改造
  • 2. unordered_map
  • 3. unordered_set

    C++ STL 库中,unordered_map 和 unordered_set 容器的底层为哈希表,本文将简单模拟哈希表(哈希桶),unordered_map 和 unordered_set 只需封装哈希表的接口即可实现。

    1. 哈希表的改造

    1. 模板参数列表的改造

      • K:关键码类型
      • T:不同容器 T 的类型不同,如果是 unordered_map,T 代表一个键值对,如果是 unordered_set,T 为 K
      • KeyOfT:从 T 中获取 Key
      • Hash:哈希函数仿函数对象类型,哈希函数使用除留余数法,需要将 Key 转换为整型数字才能取模
        templateclass HashTable;
      • 增加迭代器操作

        // 为了实现简单,在哈希桶的迭代器类中需要用到HashTable本身templateclass HashTable;// 注意:因为哈希桶在底层是单链表结构,所以哈希桶的迭代器不需要--操作templatestruct __HTIterator{typedef HashNode Node;typedef HashTable HT;typedef __HTIterator Self;Node* _node;// 当前迭代器关联的节点HT* _ht;// 哈希桶 - 主要是为了找下一个空桶时候方便__HTIterator(Node* node, HT* ht): _node(node), _ht(ht){}T& operator*(){return _node->_data;}Self& operator++(){if (_node->_next){// 当前桶还是节点_node = _node->_next;}else{// 当前桶走完了,找下一个桶KeyOfT kot;Hash hs;size_t hashi = hs(kot(_node->_data)) % _ht->_tables.size();// 找下一个桶hashi++;while (hashi _tables.size()){if (_ht->_tables[hashi]){_node = _ht->_tables[hashi];break;}hashi++;}// 后面没有桶了if (hashi == _ht->_tables.size()){_node = nullptr;}}return *this;}bool operator!=(const Self& s){return _node != s._node;}};
      • 增加通过 T 获取 key 操作

        templateclass HashTable{templatefriend struct __HTIterator;typedef HashNode Node;public:typedef __HTIterator iterator;iterator begin(){for (size_t i = 0; i _next;delete cur;cur = next;}_tables[i] = nullptr;}}bool Insert(const T& data){KeyOfT kot;if (Find(kot(data)))return false;Hash hs;// 负载因子到1就扩容if (_n == _tables.size()){vector newTables(_tables.size() * 2, nullptr);for (size_t i = 0; i _next;// 头插到新表size_t hashi = hs(kot(cur->_data)) % newTables.size();cur->_next = newTables[hashi];newTables[hashi] = cur;cur = next;}_tables[i] = nullptr;}_tables.swap(newTables);}size_t hashi = hs(kot(data)) % _tables.size();Node* newnode = new Node(data);// 头插newnode->_next = _tables[hashi];_tables[hashi] = newnode;++_n;return true;}Node* Find(const K& key){KeyOfT kot;Hash hs;size_t hashi = hs(key) % _tables.size();Node* cur = _tables[hashi];while (cur){if (kot(cur->_data) == key){return cur;}cur = cur->_next;}return nullptr;}bool Erase(const K& key){KeyOfT kot;Hash hs;size_t hashi = hs(key) % _tables.size();Node* prev = nullptr;Node* cur = _tables[hashi];while (cur){if (kot(cur->_data) == key){// 删除if (prev){prev->_next = cur->_next;}else{_tables[hashi] = cur->_next;}delete cur;--_n;return true;}prev = cur;cur = cur->_next;}return false;}private:vector _tables;// 指针数组size_t _n;};

    2. unordered_map

    • unordered_map 中存储的是 pair 的键值对,K 为 key 的类型,V 为 value 的类型,Hash 为哈希函数类型
    • unordered_map 在实现时,只需将 HashTable 中的接口重新封装即可
      templateclass unordered_map{// 通过T获取key的操作struct MapKeyOfT{const K& operator()(const pair& kv){return kv.first;}};public:typedef typename hash_bucket::HashTable::iterator iterator;iterator begin(){return _ht.begin();}iterator end(){return _ht.end();}bool insert(const pair& kv){return _ht.Insert(kv);}private:hash_bucket::HashTable _ht;};

      3. unordered_set

      • unordered_set 的实现类似于 unordered_map
        templateclass unordered_set{struct SetKeyOfT{const K& operator()(const K& key){return key;}};public:typedef typename hash_bucket::HashTable::iterator iterator;iterator begin(){return _ht.begin();}iterator end(){return _ht.end();}bool insert(const K& key){return _ht.Insert(key);}private:hash_bucket::HashTable _ht;};

        END

上一篇:怎么备份宝塔面板数据?

下一篇:HTML按钮颜色定制秘籍,一键改变按钮风格!