HashTable,HashMap,HashSet

#pragma once
#include<vector>
#include<string>
template<class K>
struct SetKeyOfT
{
	const K& operator()(const K& key) {
		return key;
	}
};

namespace bit {
	using std::vector;
	using std::string;
	using std::pair;
	template<class T>
	struct HashNode
	{
		T _data;
		HashNode<T>* _next;
		HashNode(const T& data)
		:_data(data)
		,_next(nullptr)
		{

		}
	};
	//前置声明
	template<class K, class T, class KeyOfT, class Hash>
	class HashTable;

	template<class K,class T,class KeyOfT,class Hash>
	struct __HashTableIterator
	{
		typedef __HashTableIterator<K, T, KeyOfT,Hash> Self;
		typedef HashTable<K, T, KeyOfT, Hash> HT;
		typedef HashNode<T> Node;
		Node* _node;
		HT* _pht;


		__HashTableIterator(Node* node,HT* _pht)
			:_node(node)
			,_pht(_pht)
		{}

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

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

		Self operator++() {
			if (_node->_next)
				_node = _node->_next;
			else
			{
				//如果一个桶走完了,找到下一个桶继续 
				KeyOfT koft;
				size_t i = _pht->HashFunc(koft(_node->_data)) % _pht->_tables.size();
				++i;
				for (; i < _pht->_tables.size(); i++)
				{
					Node* cur = _pht->_tables[i];
					if (cur)
					{
						_node = cur;
						return *this;
					}
				}
				_node = nullptr;
				return *this;
			}
		}

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

	};

	template<class K>
	struct _Hash
	{
		const K& operator()(const K& key)
		{
			return key;
		}
	};
	//特化
	template<>
	struct _Hash<string>
	{
		size_t operator()(const string& key)
		{
			size_t hash = 0;
			for (size_t i = 0; i < key.size(); ++i)
			{
				hash *= 131;
				hash += key[i];
			}
			return hash;
		}
		
	};

	template<class K,class T,class KeyOfT,class Hash = _Hash<K>>
	class HashTable
	{
		typedef HashNode<T> Node;
	public:
		friend struct __HashTableIterator<K, T, KeyOfT, Hash>;
		typedef __HashTableIterator<K, T, KeyOfT,Hash> iterator;
		iterator begin()
		{
			for (size_t i = 0; i < _tables.size();i++)
			{
				if (_tables[i]) {
					return iterator(_tables[i],this);
				}
			}
			return end();
		}

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

		~HashTable()
		{
			Clear();
		}
		void Clear()
		{
			for (size_t i = 0; i < _tables.size(); ++i)
			{
				Node* cur = _tables[i];
				while (cur)
				{
					Node* next = cur->_next;
					delete cur;
					cur = next;
				}
				_tables[i] = nullptr;
			}
		}
		size_t HashFunc(const K& key) {
			Hash hash;
			return hash(key);
		}

		size_t GetNextPrime(size_t prime)
		{
			const int PRIMECOUNT = 28;
			static const size_t primeList[PRIMECOUNT] =
			{
			53ul, 97ul, 193ul, 389ul, 769ul,
			1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
			49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
			1572869ul, 3145739ul, 6291469ul, 12582917ul,
			25165843ul,
			50331653ul, 100663319ul, 201326611ul, 402653189ul,
			805306457ul,
			1610612741ul, 3221225473ul, 4294967291ul
			};
			for (size_t i = 0; i < PRIMECOUNT; ++i)
			{
				if (primeList[i] > _num)
				{
					return primeList[i];
				}
				return primeList[PRIMECOUNT - 1];
			}
		}
		pair<iterator, bool> Insert(const T& data) {
			KeyOfT koft;
			//如果负载因子等于1,则增容,避免大量的哈希冲突
			if (_tables.size() == _num) {
				//1.开二倍大小的新表(不一定是二倍)
				//2.遍历旧表的数据,重新计算在新表中的位置
				//3.释放旧表
				vector<Node*> newtables;
				//size_t newsize = _tables.size() == 0 ? 19 : _tables.size() * 2;
				size_t newsize = GetNextPrime(_tables.size());
				newtables.resize(newsize);
				for (size_t i = 0; i < _tables.size(); i++) {
					//将旧表中的节点取下来重新计算在新表中的位置,并插入进去
					Node* cur = _tables[i];
					//遍历桶里面的元素
					while (cur) {
						Node* next = cur->_next;
						size_t index = HashFunc(koft(cur->_data)) % newtables.size();
						cur->_next = newtables[index];
						newtables[index] = cur;
						cur = next;
					}
					_tables[i] = nullptr;
				}
				_tables.swap(newtables);
			}
			size_t index = HashFunc(koft(data)) % _tables.size();
			//先查找在不在表里
			Node* cur = _tables[index];
			while (cur) {
				if (koft(cur->_data) == koft(data))
				{
					return make_pair(iterator(cur,this),false);
				}
				else {
					cur = cur->_next;
				}
			}
			//头插(尾差也可)
			Node* newnode = new Node(data);
			newnode->_next = _tables[index];
			_tables[index] = newnode;
			++_num;
			return make_pair(iterator(newnode, this), true);
		}
		Node* Find(const K& key) {
			size_t index = HashFunc(key) % _tables.size();
			Node* cur = _tables[index];
			while (cur) {
				if (koft(cur->_data)==key ){
					return cur;
				}
				else {
					cur = cur->_next;
				}
			}
			return nullptr;
		}
		bool Erase(const K& key) {
			KeyOfT koft;
			size_t index = HashFunc(key) % _tables.size();
			Node* cur = _tables[index];
			Node* prev = nullptr;
			while (cur)
			{
				if (koft(cur->_data) == key) {
					if (prev == nullptr) {
						//表示要删的值在第一个节点
						_tables[index] = cur->_next;
					}else{
						prev->_next = cur->_next;
					}
					delete cur;
					return true;
				}
				else {
					cur = cur->_next;
				}
			}
			return false;
		} 
	private:
		vector<Node*> _tables;
		size_t _num = 0;//记录表中存储的数据个数
	};
	void TestHashTable() {
		HashTable<int, int, SetKeyOfT<int>> ht;
	/*	ht.Insert(4);
		ht.Insert(14);
		ht.Insert(24);
		ht.Insert(5);
		ht.Insert(15);
		ht.Insert(25);
		ht.Insert(6);
		ht.Insert(16);
		ht.Insert(26);
		ht.Insert(36);
		ht.Insert(33);
		ht.Erase(4);
		ht.Erase(14);*/
	}
	void TestHashTable2() {
		HashTable<string, string, SetKeyOfT<string>> ht;
		/*ht.Insert("sort");
		ht.Insert("string");
		ht.Insert("left");*/
	}
}

HashMap

#pragma once
#include"HashTable.h"
#include<utility>
namespace bit
{
	using std::pair;
	using std::endl;    
	using std::make_pair;
	template<class K,class V, class Hash = _Hash<K>>
	class unordered_map
	{
		struct MapKofT
		{
			const K&  operator()(const pair<K, V>& kv)
			{
				return kv.first;
			}
		};
	public:
		typedef typename HashTable<K, pair<K,V>, MapKofT, Hash>::iterator iterator;
		iterator begin()
		{
			return _ht.begin();
		}
		iterator end()
		{
			return _ht.end();
		}
		pair<iterator,bool> insert(const pair<K, V>& kv) {
			return _ht.Insert(kv);
		}
		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>, MapKofT,Hash> _ht;
	};
	void test_unorderedmap()
	{
		unordered_map<string, string> dict;
		dict.insert(make_pair("sort", "排序"));
		dict.insert(make_pair("left", "左边"));
		dict.insert(make_pair("string", "字符串"));
		dict["left"] = "hhh";
		dict["end"] = "尾部";
		auto it = dict.begin();
		while (it != dict.end()) {
			cout << it->first << ":"<<it->second<<endl;
			++it;
		}
	}
}

HashSet

#pragma once
#include"HashTable.h"
#include<iostream>
namespace bit
{
	using std::cout;

	template<class K,class Hash = _Hash<K>>
	class unordered_set
	{
	private:
		struct SetKofT
		{
			const K&  operator()(const K& k)
			{
				return k;
			}
		};
	public:
		typedef typename HashTable<K, K, SetKofT, Hash>::iterator iterator;
		iterator begin()
		{
			return _ht.begin();
		}
		iterator end()
		{
			return _ht.end();
		}
		pair<iterator,bool> insert(const K& k) {
			return _ht.Insert(k);
		}
	private:
		HashTable<K, K, SetKofT,Hash> _ht;
	};
	void test_unorderedset()
	{
		unordered_set<int> s;
		s.insert(1);
		s.insert(5);
		s.insert(4);
		s.insert(2);

		auto it = s.begin();
		while (it != s.end()) {
			cout << *it << " ";
			++it;
		}
	}
}

BItSet

#pragma once
#include<vector>
#include<iostream>
namespace bit
{
	using std::cout;
	using std::endl;
	class bitset
	{
	public:
		bitset(size_t N)
		{
			_bits.resize(N / 32 + 1, 0);
			_num = 0;
		}
		void set(size_t x)
		{
			size_t index = x / 32;//计算映射位置在第几个整型
			size_t pos = x % 32;//算出x在整型第几个位
			_bits[index] |= (1 << pos);//第pos个位置成1
		}

		void reset(size_t x)
		{
			size_t index = x / 32;//计算映射位置在第几个整型
			size_t pos = x % 32;//算出x在整型第几个位
			_bits[index] &= ~(1 << pos);//第pos个位置成1
		}
		bool test(size_t x) {
			size_t index = x / 32;//计算映射位置在第几个整型
			size_t pos = x % 32;//算出x在整型第几个位
			return _bits[index] & (1 << pos);
		}
	private:
		std::vector<int> _bits;
		size_t _num;//映射存储多少个数据
	};
	void test_bitset()
	{
		bitset bs(100);
		bs.set(99);
		bs.set(98);
		bs.set(97);
		bs.set(5);
		bs.reset(98);
		for (size_t i = 0; i < 100; i++) {
			cout << i << ":" << bs.test(i)<<endl;
		}
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值