C++ 使用哈希表封装模拟实现unordered_map unordered_set

本文对比了unordered_map、unordered_set与map、set的区别,重点介绍了C++中通过哈希表封装模拟实现unordered_map和unordered_set的过程,包括关键代码和解析,同时阐述了对关键值类型的要求,如哈希函数和相等比较。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、unordered_map unordered_set 和 map set的区别

1. map set底层采取的红黑树的结构,unordered_xxx 底层数据结构是哈希表。unordered_map容器通过key访问单个元素要比map快,但它通常在遍历元素子集的范围迭代方面效率较低。

2. Java中对应的容器名为 HashMap HashSet TreeMap TreeSet,命名方面比C++好了很多。主要是早期C++并没有实现哈希结构的容器(C++11之前),也就是unordered系列,在C++11中新增了unordered_map,unordered_set,unordered_multimap,unordered_multiset,故因为历史命名问题,取了这样的名字。

3. 它们的使用大体上几乎一致。显著的差别是:
a、map和set为双向迭代器,unordered_xxx和是单向迭代器。
b、map和set存储为有序存储(红黑树结构,中序遍历有序),unordered_xxx为无序存储(哈希表的结构致使)

4. 性能差异:采取哈希表的unordered系列容器在大量数据的增删查改效率更优,尤其是查(搜索)

二、实现代码

HashTable.h

//
// Created by yangzilong on 2022/11/15.
//
#pragma once
#include <utility>
#include <vector>
#include <iostream>
using namespace std;

// 开散列(链地址法)解决哈希表中的哈希冲突

    // 哈希表中的结点并不知道自己存储的数据类型,unordered_map为pair,unordered_set为key
    template <class T>
    struct HashNode
    {
        HashNode<T>(const T& data)
        :_data(data)
        { }
        T _data;
        HashNode* _next = nullptr;
    };

    // 哈希表的前置声明,因为迭代器中要用到
    template <class , class , class , class , class >
    class HashTable;

    // 哈希表迭代器,因为数据成员中有哈希表指针,所以这些模板参数都需要
    template <class K, class T, class KeyOfT, class Hash, class Equal>
    struct __HashTable_Iterator
    {
        typedef HashNode<T> Node;
        typedef HashTable<K, T, KeyOfT, Hash, Equal> HT;
        typedef __HashTable_Iterator<K, T, KeyOfT, Hash, Equal> Self;

        __HashTable_Iterator(Node* node, HT* ptr)
        : _node(node), _tablePtr(ptr)
        { }

        bool operator==(const Self& it) const {
            return _node == it._node;
        }

        bool operator!=(const Self& it) const {
            return _node != it._node;
        }

        T& operator*() const {
            return _node->_data;
        }

        T* operator->() const {
            return &_node->_data;
        }

        // unordered_map unordered_set为单向迭代器
        Self& operator++() {
            // 前置++
            if(_node->_next)
                _node = _node->_next;
            else {
                KeyOfT kot;
                Hash hash;
                size_t hashAddress = hash(kot(_node->_data)) % _tablePtr->_table.size();
                ++hashAddress;
                _node = nullptr;
                while(hashAddress < _tablePtr->_table.size() && (_node = _tablePtr->_table[hashAddress]) == nullptr)
                    ++hashAddress;
//                while(hashAddress < _tablePtr->_table.size() && _tablePtr->_table[hashAddress] == nullptr)
//                    ++hashAddress;
//                if(hashAddress == _tableP
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值