C++|哈希结构封装unordered_set和unordered_map

目录

一、改造哈希表

1.1模板参数列表的改造

1.2增加哈希表迭代器操作

1.2.1哈希表迭代器框架

1.2.2operator*() && operator->()

1.2.3operator++()

1.2.4operator--()

1.2.5operator==() && operator!=()

二、如何用哈希表搭配unordered_map和unordered_set(仿函数)

三、哈希表封装unordered_map和unordered_set(简易版)

3.1哈希表的实现(HashTable.h)

3.2unordered_map的模拟实现(My_Unordered_Map.h)

3.3unordered_set的模拟实现(My_Unordered_Set.h)

3.4测试(test.cpp)


上一篇章,学习了unordered系列容器的使用,以及哈希结构,那么这一篇章将通过哈希结构来封装unordered系列容器,来进一步的学习他们的使用以及理解为何是如此使用。其实,哈希表的封装方式和红黑树的封装方式形式上是差不多的,如果有了红黑树的封装理解经验,我相信在理解哈希封装的过程会减少负担的。当然,在使用哈希结构中采用的是更具代表的哈希桶,接下来进行封装。

一、改造哈希表

1.1模板参数列表的改造

同理模板参数列表的改造跟红黑树的改造差不多。

K:关键码类型

V:不同容器v的容器类型不同,如果是unordered_map,v代表一个键值对,如果是unordered_set,v为k

KeyOfT:因为v的类型不同,通过keyOfT取key的方式就不同 。

Hash:哈希函数仿函数对象类型,哈希函数使用除留余数法,需要将字符串类型转化为整形数字才能取模。

1.2增加哈希表迭代器操作

1.2.1哈希表迭代器框架

    //前置声明,迭代器中才能定义HashTable对象
	template<class K, class T, class KeyOfT, class hash>
	class HashTable;

	template<class K,class T,class Ref,class Ptr,class KeyOfT,class hash = HashFunc<K>>
	struct _HTIterator
	{
		typedef _HTIterator<K,T, Ref, Ptr,KeyOfT,hash> Self;//方便作为接收迭代器操作的返回值的类型
		typedef HashNode<T> Node;
		typedef Node* PNode;

		PNode _node;//定义节点指针,方便访问其成员来完成迭代器的操作
		HashTable<K, T, KeyOfT, hash>* _ht;//定义哈希表指针,方便使用其成员来完成迭代器的操作
		size_t _hashi;//记录迭代器访问的位置

		_HTIterator(PNode node, HashTable<K, T, KeyOfT, hash>* ht,size_t hashi)
			:_node(node)
			,_ht(ht)
			,_hashi(hashi)
		{}

        //....
    };

1.2.2operator*() && operator->()

    	Ref operator*()
		{
			return _node->_data;
		}

		Ptr operator->()
		{
			return &(_node->_data);
		}

1.2.3operator++()

        Self& operator++()
		{
			if (_node->_next)//下一个元素不为空
			{
				_node = _node->_next;
			}
			else
			{
				/*hash hs;
				KeyOfT oft;
				int hashi = hs(oft(this->_data) % _tables.size());*/
                //寻找下一个不为空的桶
				++_hashi;
				while(_hashi < _ht->_tables.size())
				{
					if (_ht->_tables[_hashi] != nullptr)
					{
						_node = _ht->_tables[_hashi];
						break;
					}
					++_hashi;
				}
                //到末尾还没有找到不为空的桶
				if(_hashi == _ht->_tables.size())
					_node = nullptr;
				
			}
			return *this;

		}

1.2.4operator--()

        Self operator--()
		{
			PNode cur = _ht->_tables[_hashi];
			
			//当前节点就是第一个节点
			if (cur->_next == nullptr)
			{
				//寻找上一个非空桶
				--_hashi;
				while (_hashi)
				{
					//寻找该非空桶的最后一个元素
					if (_ht->_tables[_hashi])
					{
						cur = _ht->_tables[_hashi];
						while (cur->_next)
						{
							cur = cur->_next;
						}
						_node = cur;
						break;
					}
					_hashi--;
				}

			}
			else
			{
				while (cur->_next != _node)
				{
					cur = cur->_next;
				}
				_node = cur;
			}
            return *this;
		}

1.2.5operator==() && operator!=()

		bool operator==(const Self& x)
		{
			return _node == x._node;//由于没有重复的元素,直接比较节点的地址
		}

		bool operator!=(const Self& x)
		{

			return _node != x._node;
		}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值