【C++】unordered_map和unordered_set的模拟实现

本文详细介绍了C++中unordered_map和unordered_set的模板类实现,包括它们如何通过哈希表进行操作,如插入、查找和删除键值对,以及相关的结构体和迭代器定义。
摘要由CSDN通过智能技术生成

目录

前言

unordered_map的模拟实现

unordered_set的模拟实现


前言

  • unordered_map和unordered_set的模拟实现是通过封装哈希表来实现的,可以去看我模拟实现哈希表的博客模拟实现哈希表

unordered_map的模拟实现

  • 全部代码

 template<class K, class T,class Hash = hash_bucket::HashFunc<K>>
 class unordered_map
 {
 public:

  struct unordered_mapKeyOfType
  {
   const K& operator()(const pair<K, T>& kT)
   {
    return kT.first;
   }
  };

  typedef typename hash_bucket::HashTable<K, pair<const K, T>, unordered_mapKeyOfType, Hash>::iterator iterator;

  iterator begin()
  {
   return _ht.begin();
  }

  iterator end()
  {
   return _ht.end();
  }

  
  pair<iterator, bool> Insert(const pair<K, T>& kv)
  {
   return _ht.Insert(kv);
  }

  T& operator[](const K& key)
  {
   pair<iterator, bool> ret = _ht.Insert(make_pair(key, T()));
   return ret.first->second;
  }

  const T& operator[](const K& key) const
  {
   pair<iterator, bool> ret = _ht.Insert(make_pair(key, T()));
   return ret.first->second;
  }

  iterator Find(const K& key)
  {
   return _ht.Find(key);
  }

  bool Erase(const K& key)
  {
   return _ht.Erase(key);
  }

 private:
  hash_bucket::HashTable<K, pair<K, T>, unordered_mapKeyOfType> _ht;
 };

  • unordered_map 模板类

template<class K, class T, class Hash = hash_bucket::HashFunc<K>>  
class unordered_map  
{  
    // ...  
};

unordered_map`是一个模板类,接受三个模板参数: K:键的类型。 T:值的类型。 Hash:哈希函数类型,默认为hash_bucket::HashFunc。

  • 结构体 unordered_mapKeyOfType

struct unordered_mapKeyOfType  
{  
    const K& operator()(const pair<K, T>& kT)  
    {  
        return kT.first;  
    }  
};

这个结构体定义了一个函数对象,用于从pair<K, T>中提取键(kT.first)。

  • 类型别名 iterator

typedef typename hash_bucket::HashTable<K, pair<const K, T>, unordered_mapKeyOfType, Hash>::iterator iterator;

这里定义了一个类型别名iterator,它实际上是hash_bucket::HashTable的迭代器类型。

成员函数

  • begin() 和 end():返回哈希表的开始和结束迭代器。

iterator begin()
  {
   return _ht.begin();
  }

iterator end()
  {
   return _ht.end();
  }

  • Insert(const pair<K, T>& kv):插入一个键值对,并返回一个包含迭代器和一个布尔值的pair。迭代器指向新插入的元素,布尔值表示是否成功插入(如果键已存在,则不会插入)。

  pair<iterator, bool> Insert(const pair<K, T>& kv)
  {
   return _ht.Insert(kv);
  }

  T& operator[](const K& key)
  {
   pair<iterator, bool> ret = _ht.Insert(make_pair(key, T()));
   return ret.first->second;
  }

  • operator[](const K& key) 和 const operator[](const K& key) const:通过键访问值。如果键不存在,则插入一个具有默认构造的值的键值对。

  const T& operator[](const K& key) const
  {
   pair<iterator, bool> ret = _ht.Insert(make_pair(key, T()));
   return ret.first->second;
  }

  • Find(const K& key):查找键对应的迭代器。

  iterator Find(const K& key)
  {
   return _ht.Find(key);
  }


  • Erase(const K& key):删除键对应的键值对,并返回是否成功删除。

  bool Erase(const K& key)
  {
   return _ht.Erase(key);
  }

  • 私有成员

hash_bucket::HashTable<K, pair<K, T>, unordered_mapKeyOfType> _ht;

这里定义了一个私有成员_ht,它是一个hash_bucket::HashTable的实例,用于存储键值对。

unordered_set的模拟实现

  • 全部代码

 template<class K, class Hash = hash_bucket::HashFunc<K>>
 class unordered_set
 {
 public:

  struct unordered_setKeyOfType
  {
   const K& operator()(const K& key)
   {
    return key;
   }
  };

  typedef typename hash_bucket::HashTable<K, K, unordered_setKeyOfType, Hash>::const_iterator iterator;
  typedef typename hash_bucket::HashTable<K, K, unordered_setKeyOfType, Hash>::const_iterator const_iterator;

  const_iterator begin() const
  {
   return _ht.begin();
  }

  const_iterator end() const
  {
   return _ht.end();
  }

  pair<const_iterator, bool> Insert(const K& key)
  {
   auto ret = _ht.Insert(key);
   return pair<const_iterator, bool>(const_iterator(ret.first._node, ret.first._pht, ret.first._hashi), ret.second);
  }

  iterator Find(const K& key)
  {
   return _ht.Find(key);
  }

  bool erase(const K& key)
  {
   return _ht.Erase(key);
  }

  bool Erase(const K& key)
  {
   return _ht.Erase(key);
  }
 private:
  hash_bucket::HashTable<K, K, unordered_setKeyOfType> _ht;
 };
  • 模板参数

template<class K, class Hash = hash_bucket::HashFunc<K>>

这个模板类接受两个模板参数: K:集合中元素的类型。 Hash:哈希函数类型,默认为hash_bucket::HashFunc。

  • 结构体 unordered_setKeyOfType

struct unordered_setKeyOfType  
{  
    const K& operator()(const K& key)  
    {  
        return key;  
    }  
};

这个结构体定义了一个函数对象,它简单地返回其输入参数。对于unordered_set来说,这个函数对象用于从元素中提取键(在这种情况下,键就是元素本身)。

  • 类型别名 iterator 和 const_iterator

typedef typename hash_bucket::HashTable<K, K, unordered_setKeyOfType, Hash>::const_iterator iterator;  
typedef typename hash_bucket::HashTable<K, K, unordered_setKeyOfType, Hash>::const_iterator const_iterator;

这里定义了两个类型别名,iterator和const_iterator。然而,这里有一个问题:两个别名都指向const_iterator,这意味着即使iterator的名字暗示它是非const的,实际上它也是const的。这可能是一个错误,通常iterator应该指向非const迭代器,而const_iterator指向const迭代器。

成员函数

  • begin() 和 end():返回集合的开始和结束迭代器。由于定义的问题,这两个函数返回的都是const迭代器。
      const_iterator begin() const
       {
        return _ht.begin();
       }
    
       const_iterator end() const
       {
        return _ht.end();
       }
    
    
  • Insert(const K& key):插入一个元素,并返回一个包含迭代器和一个布尔值的pair。迭代器指向新插入的元素(如果成功插入),布尔值表示是否成功插入。注意,这里对返回的迭代器进行了转换,使用了底层的_node、_pht和_hashi成员,这可能意味着hash_bucket::HashTable的迭代器不是直接兼容的,需要进行适配。
      pair<const_iterator, bool> Insert(const K& key)
       {
        auto ret = _ht.Insert(key);
        return pair<const_iterator, bool>(const_iterator(ret.first._node, ret.first._pht, ret.first._hashi), ret.second);
       }
    
    
    
  • Find(const K& key):查找给定键的迭代器。
      iterator Find(const K& key)
       {
        return _ht.Find(key);
       }
    
  • erase(const K& key) 和 Erase(const K& key):这两个函数是等价的,都用于删除集合中指定键的元素,并返回是否成功删除。注意这里有两个名称相同但大小写不同的函数,这通常是不推荐的做法,可能会导致混淆。
     bool Erase(const K& key)
       {
        return _ht.Erase(key);
       }
    
  • 私有成员

hash_bucket::HashTable<K, K, unordered_setKeyOfType> _ht;

_ht是unordered_set类的私有成员,它是一个hash_bucket::HashTable的实例,用于存储集合中的元素。这里,键和值都是K类型的元素,因为unordered_set不存储与键相关联的值(它只存储键)。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值