ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C++实现unordermap容器和unorderset容器

2021-05-28 20:01:37  阅读:204  来源: 互联网

标签:容器 return cur iterator insert unordermap ht unorderset size


代码如下:

#include <iostream>
#include <vector>
using namespace std;


template<typename K,typename V,typename KeyOfValue>
class HashTable;//声明

template<typename V>
struct HashNode
{
	typedef HashNode<V> Node;
	V _val;
	Node * _next;

	HashNode(const V & val):_val(val),_next(nullptr){}
};

template<typename K,typename V,typename KeyOfValue>
struct HashIterator
{
	typedef HashNode<V> Node;
	typedef HashIterator<K, V, KeyOfValue> Self;
	typedef HashTable<K, V, KeyOfValue>HT;
	Node *_node;
	HT * _hPtr;

	HashIterator(Node *node,HT *hPtr):_node(node),_hPtr(hPtr){}

	V &operator*()
	{
		return _node->_val;
	}

	V *operator->()
	{
		return &_node->_val;
	}

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

	Self & operator++()
	{
		if (_node->_next)
		{
			_node = _node->_next;
		}
		else
		{
			KeyOfValue kov;
			size_t idx = kov(_node->_val) % _hPtr->_ht.size();

			++idx;
			for (; idx < _hPtr->_ht.size(); idx++)
			{
				if (_hPtr->_ht[idx])
				{
					_node = _hPtr->_ht[idx];
					break;
				}
			}

			if (idx == _hPtr->_ht.size()) _node = nullptr;
		}
		return *this;
	}

};

template<typename K,typename V,typename KeyOfValue>
class HashTable
{
public:
	typedef HashIterator<K, V, KeyOfValue> iterator;
	typedef HashNode<V> Node;

	template<typename K,typename V,typename KeyOfValue>
	friend struct HashIterator;

	HashTable(int n = 10):_ht(n),_size(0){}

	iterator begin()
	{
		for (size_t i = 0; i < _ht.size(); i++)
		{
			if (_ht[i])
			{
				return iterator(_ht[i], this);
			}
		}
		return iterator(nullptr, this);
	}

	iterator end()
	{
		return iterator(nullptr, this);
	}

	pair<iterator, bool> insert(const V & val)
	{

		//0.检查容量
		checkCapacity();

		KeyOfValue kov;

		//1.计算hash位置
		int idx = kov(val) % _ht.size();

		//2.查找
		Node *cur = _ht[idx];
		while (cur)
		{
			if (kov(cur->_val) == kov(val)) return make_pair(iterator(cur, this), false);
			cur = cur->_next;
		}

		//3.插入--头插
		cur = new Node(val);
		cur->_next = _ht[idx];
		_ht[idx] = cur;
		++_size;
		return make_pair(iterator(cur, this), true);
	}

	void checkCapacity()
	{
		if (_size == _ht.size())
		{
			int newC = _size == 0 ? 10 : 2 * _size;

			vector<Node *>newHt(newC);

			KeyOfValue kov;

			for (size_t i = 0; i < _ht.size(); i++)
			{
				Node *cur = _ht[i];

				while (cur)
				{
					Node *next = cur->_next;

					int idx = kov(cur->_val) % newHt.size();

					cur->_next = newHt[idx];
					newHt[idx] = cur;

					cur = next;
				}

				_ht[i] = nullptr;
			}

			swap(_ht, newHt);
		}
	}

private:
	vector<Node *> _ht;
	int _size;
};


template<typename K>
class UnorderedSet
{
	struct SetKeyOfValue
	{
		const K & operator()(const K & key)
		{
			return key;
		}
	};

public:
	typedef typename  HashTable<K, K, SetKeyOfValue>::iterator iterator;

	pair<iterator, bool> insert(const K& key)
	{
		return _ht.insert(key);
	}

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

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

private:
	HashTable<K, K, SetKeyOfValue> _ht;
};


template<typename K,typename V>
class UnorderedMap
{
	struct MapKeyOfValue
	{
		const K& operator()(const pair<K, V> & val)
		{
			return val.first;
		}
	};

public:
	typedef typename HashTable<K, pair<K, V>, MapKeyOfValue>::iterator iterator;

	pair<iterator, bool > insert(const pair<K, V> & val)
	{
		return _ht.insert(val);
	}

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

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

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

private:
	HashTable<K, pair<K, V>, MapKeyOfValue> _ht;
};

int main()
{
	UnorderedSet<int>s;
	s.insert(1);
	s.insert(123);
	s.insert(123412);
	s.insert(12);
	s.insert(1132);
	s.insert(1131);
	s.insert(436);
	s.insert(786);
	s.insert(13);
	s.insert(7965);
	s.insert(7653);
	s.insert(645);
	s.insert(324);

	UnorderedSet<int>::iterator it1 = s.begin();
	while (it1 != s.end())
	{
		cout << *it1 << " ";
		++it1;
	}
	cout << endl;

	for (const auto & e : s)
	{
		cout << e << " ";
	}
	cout << endl;


	UnorderedMap<int, int>m;
	m.insert(make_pair(1, 1));
	m[2] = 2;
	m[3] = 3;

	UnorderedMap<int, int>::iterator it2 = m.begin();
	while (it2 != m.end())
	{
		cout << it2->first << "--->" << it2->second << endl;
		++it2;
	}
	cout << "--------------------" << endl;

	m[2] = 20;
	for (auto & p : m)
	{
		cout << p.first << "--->" << p.second << endl;
	}
	return 0;
}

测试结果:
在这里插入图片描述

标签:容器,return,cur,iterator,insert,unordermap,ht,unorderset,size
来源: https://blog.csdn.net/m0_51955470/article/details/117373053

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有