【DS】哈希表实现

哈希表的介绍和扩展请查看这篇文章:http://blog.csdn.net/always__/article/details/51584446


基于线性探测,二次探测的哈希表结构,实现字典查询。

代码如下:

#pragma once
#include<iostream>
#include<string>
using namespace std;

命名空间First--线性探测法
//namespace First
//{
//
//enum State
//{
//	EMPTY,
//	DELETE,
//	EXIST,
//};
//
//template<class T>
//class HashTable
//{
//public:
//	HashTable(size_t capacity = 10)
//		:_tables(new T[capacity]),
//		_states(new State[capacity]),
//		_size(0),
//		_capacity(capacity)	
//	{
//		for (size_t i = 0;i < _capacity;++i)
//		{
//			_states[i] = EMPTY;
//		}
//	}
//	~HashTable()
//	{
//		if (_tables)
//		{
//			delete []_tables;
//			delete []_states;
//		}
//	}
//	//拷贝构造函数
//	HashTable(const HashTable<T>& ht)
//		:_tables(NULL)
//		, _status(NULL)
//		,_size(0)
//		,_capacity(0)
//	{
//		HashTable<K> newTables(ht._capacity);
//		for (size_t i = 0; i < ht._capacity; ++i)
//		{
//			if (ht._status[i] == EXITS)
//			{
//				newTables.Insert(ht._tables[i]);
//			}
//		}
//
//		this->Swap(newTables);
//	}
//
//	//重载赋值运算符
//	HashTable<T>& operator=(HashTable<T> ht)
//	{
//		this->Swap(ht);
//
//		return *this;
//	}
//	bool Insert(const T& key)
//	{
//		_CheckCapacity();
//
//		/*if (_size == _capacity)
//		{
//			cout << "HashTable is Full" << endl;
//			return false;
//		}*/
//
//		size_t index = HashFunc(key);
//		//线性探测
//
//		while (_states[index] == EXIST)
//		{
//			if (_tables[index] == key)
//			{
//				return false;
//			}
//
//			++index;
//			if (index == _capacity)
//			{
//				index = 0;
//			}
//		}
//		_tables[index] = key;
//		_states[index] = EXIST;
//		_size++;
//	}
//
//
//
//
//	改进版
//	//bool Insert(const T& key)
//	//{
//	//	_CheckCapacity();
//
//	//	/*if (_size == _capacity)
//	//	{
//	//	cout << "HashTable is Full" << endl;
//	//	return false;
//	//	}*/
//
//	//	size_t index = HashFunc0(key);
//	//	//线性探测
//
//	//	while (_states[index] == EXIST)
//	//	{
//	//		if (_tables[index] == key)
//	//		{
//	//			return false;
//	//		}
//
//	//		index = _HashFunci(index, i++);
//	//		index %= _capacity;
//	//	}
//	//	_tables[index] = key;
//	//	_states[index] = EXIST;
//	//	_size++;
//	//}
//
//
//
//
//
//
//
//	bool Find(const T& key)
//	{
//		size_t index = HashFunc(key);
//		size_t start = index;
//		bool find = false;
//
//		while (_states[index] != EMPTY)
//		{
//			if (_tables[index] == key )
//			{
//				if (_states[index] != DELETE)
//				{
//					return true;
//				}
//				return false;
//			}
//
//			++index;
//			if (index == _capacity)
//			{
//				index = 0;
//			}
//			if (index == start)
//			{
//				return false;
//			}
//		}
//		return false;
//	}
//
//	bool Remove(const T& key)
//	{
//		size_t index = HashFunc(key);
//		size_t start = index;
//
//		while (_states[index] != EMPTY)
//		{
//			if (_tables[index] == key)
//			{
//				_states[index] = DELETE;
//				_size--;
//				return true;
//			}
//
//			++index;
//			if (index == _capacity)
//			{
//				index = 0;
//			}
//			if (index == start)
//			{
//				return false;
//			}
//		}
//	}
//	void Print()
//	{
//		for (size_t i = 0;i < _capacity;++i)
//		{
//			printf("[%d : %d]--\n", _states[i], _tables[i]);
//		}
//		cout << endl;
//	}
//protected:
//	void Swap(HashTable<T> &tmp)
//	{
//		swap(_tables, tmp._tables);
//		swap(_states, tmp._states);
//		swap(_size, tmp._size);
//		swap(_capacity, tmp._capacity);
//	}
//	size_t HashFunc(const T& key)
//	{
//		return key%_capacity;
//	}
//	
//	void _CheckCapacity()
//	{
//		if (_size * 10 / _capacity == 7)
//		{
//			HashTable<T> tmp(2 * _capacity);
//			for (size_t i = 0;i < _capacity;++i)
//			{
//				if (_states[i] == EXIST)
//				{
//					tmp.Insert(_tables[i]);
//				}
//			}
//			this->Swap(tmp);
//		}
//	}
//
//
//protected:
//	T* _tables;			//哈希表
//	State* _states;	    //状态表
//	size_t _size;		//大小
//	size_t _capacity;		
//};
//}
//
//
命名空间Second--闭散列的二次探测
//namespace Second
//{
//	enum State
//	{
//		EMPTY,
//		DELETE,
//		EXIST,
//	};
//
//	template<class T>
//	class HashTable
//	{
//	public:
//		HashTable(size_t capacity = 10)
//			:_tables(new T[capacity]),
//			_states(new State[capacity]),
//			_size(0),
//			_capacity(capacity)
//		{
//			for (size_t i = 0;i < _capacity;++i)
//			{
//				_states[i] = EMPTY;
//			}
//		}
//		~HashTable()
//		{
//			if (_tables)
//			{
//				delete[]_tables;
//				delete[]_states;
//			}
//		}
//		bool Insert(const T& key)
//		{
//			_CheckCapacity();
//			size_t index = HashFunc(key);
//			int i = 1;
//			while (_states[index] ==EXIST)
//			{
//				if (_tables[index] == key)
//				{
//					return false;
//				}
//
//				index = HashFunc(key) + i*i;
//				index %= _capacity;
//				++i;
//
//			}
//
//			_tables[index] = key;
//			_states[index] = EXIST;
//			_size++;
//		}
//		bool Find(const T& key)
//		{
//			
//		}
//
//		bool Remove(const T& key)
//		{
//			
//		}
//		size_t HashFunc(const T& key)
//		{
//			return key%_capacity;
//		}
//		void Print()
//		{
//			for (size_t i = 0;i < _capacity;++i)
//			{
//				printf("[%d : %d]--", _states[i], _tables[i]);
//			}
//			cout << endl;
//		}
//			
//		void _CheckCapacity()
//		{
//			if (_size * 10 / _capacity == 7)
//			{
//				//重新建表
//
//				HashTable<T> tmp(2 * _capacity);
//				for (size_t i = 0;i < _capacity;++i)
//				{
//					if (_states[i] == EXIST)
//					{
//						tmp.Insert(_tables[i]);
//					}
//				}
//				this->Swap(tmp);
//			}
//		}
//		void Swap(HashTable<T> &tmp)
//		{
//			swap(_tables, tmp._tables);
//			swap(_states, tmp._states);
//			swap(_size, tmp._size);
//			swap(_capacity, tmp._capacity);
//		}
//	protected:
//		T* _tables;			//哈希表
//		State* _states;	    //状态表
//		size_t _size;		//大小
//		size_t _capacity;
//	};
//}

//明名空间3--哈希表的key/value形式的二次探测
namespace Third
{
	enum State
	{
		EMPTY,
		DELETE,
		EXIST,
	};

	template<class K, class V>
	struct HashTableNode
	{
		HashTableNode()
		{}
		HashTableNode(const K& key, const V& value)
			:_key(key),
			_value(value)
		{}

		K _key;
		V _value;
	};

	static size_t StringHash(const char* str)
	{
		size_t sum = 0;
		while (*str != '\0')
		{
			sum += *str;
			str++;
		}
		return sum;
	}

	template<class K>
	struct __HashFunc
	{
		size_t operator()(const K& key)
		{
			return key;
		}
	};
	//模板特化
	template<>
	struct __HashFunc<string>
	{
		size_t operator()(const string& str)
		{
			return StringHash(str.c_str());
		}
	};


	template<class K, class V, class HashFunction = __HashFunc<K>>
	class HashTable
	{
		typedef HashTableNode<K, V> Node;
	public:
		HashTable()
			:_tables(NULL)
			, _size(0)
			, _capacity(0)
			, _status(0)
		{}
		HashTable(size_t capacity = 10)
			:_tables(new Node[capacity]),
			_states(new State[capacity]),
			_size(0),
			_capacity(capacity)
		{
			for (size_t i = 0;i < capacity;++i)
			{
				_states[i] = EMPTY;
			}
		}
		~HashTable()
		{
			if (_tables)
			{
				delete[]_tables;
				delete[]_states;
			}
		}

		bool Insert(const K& key, const V& value)
		{
			_CheckCapacity();

			size_t index = HashFunc(key);
			int i = 1;

			//基于二次探测
			while (_states[index] == EXIST)
			{
				if (_tables[index]._key == key)
				{
					return false;
				}

				index = HashFunc(key) + i*i;
				index %= _capacity;
				++i;
			}

			_tables[index] = Node(key, value);
			_states[index] = EXIST;
			++_size;

			return true;
		}
		Node* Find(const K& key)
		{
			size_t index = HashFunc(key);

			size_t start = index;
			int i = 1;
			while (_states[index] != EMPTY)
			{
				if (_tables[index]._key == key)
				{
					if (_states[index] == EXIST)
					{
						return &(_tables[index]);
					}
					return NULL;
				}
				index += i*i;

				if (index >=_capacity)
				{
					index %= _capacity;
				}
				if (index == start)
				{
					break;
				}
			}
			return NULL;
		}

		size_t HashFunc(const K& key)
		{
			HashFunction hf;
			return (hf(key)) % _capacity;
		}
		void Print()
		{
			for (size_t i = 0;i < _capacity;++i)
			{
				cout << "【" << _tables[i]._key<<" --- ";
				cout << _tables[i]._value << "】";
			}
			cout << endl;
		}

	protected:
		void _CheckCapacity()
		{
			if (_size < _capacity)
			{
				return;
			}

			HashTable<K,V,HashFunction> newTable(2 * _capacity);
			for (size_t index = 0;index < _capacity;++index)
			{
				if (_states[index] == EXIST)
				{
					newTable._tables[index] = _tables[index];
					newTable._states[index] = EXIST;
					newTable._size = _size;
				}
			}

			this->Swap(newTable);
		}
		void Swap(HashTable<K, V, HashFunction>& other)
		{
			swap(_tables, other._tables);
			swap(_states, other._states);
			swap(_size, other._size);
			swap(_capacity, other._capacity);
		}
	protected:
		Node* _tables;
		State* _states;
		size_t _size;
		size_t _capacity;
	};

	void TestHashTable()
	{
		HashTable<string, string> ht1(10);

		ht1.Insert("dict", "字典");
		ht1.Insert("hash", "哈希");
		ht1.Insert("function", "函数");
		ht1.Insert("lauyang", "刘阳阳");

		HashTableNode<string, string>* ret = ht1.Find("lauyg");

		if (ret)
		{
			cout << "hash的中文是: " << ret->_value << endl;
		}
		else
		{
			cout << "not exist" << endl;
		}
	}
}

哈希桶实现字典查询:

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

//哈希桶key-value结构
namespace BUCKET
{
template<class K,class V>
struct HashTableNode
{
	K _key;
	V _value;
	HashTableNode<K, V>* _next;

	HashTableNode(const K& key, const V& value)
		:_key(key),
		_value(value),
		_next(NULL)
	{}
};

template<class K,class V>
class HashTable
{
	typedef HashTableNode<K, V> Node;
	typedef HashTable<K, V> Table;
public:
	
	HashTable()
		:_size(0)
	{}
	HashTable(size_t capacity)//capacity最好是素数,这样可以减少哈希冲突。
		:_size(0)
	{

 		_tables.resize(_GetNextPrime(capacity));//确保开辟素数大小空间
	}
	~HashTable()
	{
		for (size_t i = 0;i < _tables.size();++i)
		{
			Node* cur = _tables[i];
			while (cur)
			{
				Node*tmp = cur;
				cur = cur->_next;
				delete tmp;
				tmp = NULL;
			}
			_tables[i] = NULL;
		}
		_size = 0;
	}

	HashTable(const Table& other)
		:_size(0)
	{
		Table newTables(other._tables.size());
		newTables._size = other._size;

		for (size_t i = 0;i < other._tables.size();++i)
		{
			Node* cur = other._tables[i];
			Node*& head = newTables._tables[i];

			while (cur)
			{
				//newTables.Insert(cur->_key, cur->_value);

				Node* tmp= new Node(cur->_key, cur->_value);
				tmp->_next = head;
				head = tmp;
				
				cur = cur->_next;
			}
		}
		this->Swap(newTables);
	}

	/*Table& operator=(Table t)
	{
		_tables.swap(t);
		swap(_size, t._size);

		return _tables;
	}*/
	Table& operator=(Table& t)
	{
		if (this != &t)
		{
			Table tmp(t);
			_tables.swap(t);
			swap(_size, t._size);
		}
		

		return _tables;
	}
	
	bool Insert(const K& key, const V& value)
	{
		size_t index = _HashFunc(key,_tables.size());

		//检查是否存在
		Node* cur=_tables[index];
		while (cur)
		{
			if (cur->_key ==key)
			{
				return false;
			}
			cur = cur->_next;
		}

		//头插法
		Node* tmp = new Node(key, value);
		tmp->_next = _tables[index];
		_tables[index] = tmp;

		++_size;
		return true;
	}

	Node* Find(const K& key)
	{
		size_t index = _HashFunc(key, _tables.size());

		Node* cur = _tables[index];
		while (cur)
		{
			if (cur->_key == key)
			{
				return cur;
			}
			cur = cur->_next;
		}
		return NULL;
	}
	bool Remove(const K& key)
	{
		size_t index = _HashFunc(key, _tables.size());
		
		Node* cur = _tables[index];
		if (cur == NULL)
		{
			return false;
		}
		if (cur->_key == key)
		{
			_tables[index] = cur->_next;
			delete cur;
			return true;
		}
		else
		{
			Node* prev = cur;
			cur = cur->_next;
			while (cur)
			{
				if (cur->_key==key)
				{
					prev->_next = cur->_next;
					delete cur;
					return true;
				}
				prev = cur;
				cur = cur->_next;
			}
			return false;
		}
	}
	void Print()
	{
		for (size_t i = 0; i < _tables.size(); ++i)
		{
			printf("tables[%d]->", i);
			Node* cur =_tables[i];
			while (cur)
			{
				cout << "[" << cur->_key << ":" << cur->_value << "]" << "->";
				cur = cur->_next;
			}

			cout << "NULL" << endl;
		}

		cout << endl;
	}
protected:
	size_t _GetNextPrime(size_t size)
	{
		const int _PrimeSize = 28;
		static const unsigned long _PrimeList[_PrimeSize] =
		{
			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 < _PrimeSize; ++i)
		{
			if (_PrimeList[i] > size)
			{
				return _PrimeList[i];
			}
		}

		return _PrimeList[_PrimeSize - 1];
	}
	size_t _HashFunc(const K& key,size_t capacity)
	{
		return key % capacity;
	}
	void _CheckCapacity()
	{
		//负载值为1时增容
		if (_size == _tables.size())
		{
			size_t nextPrime = _GetNextPrime(_size);

			vector<Node*> newTables;
			newTables.resize(nextPrime);

			for (size_t i = 0;i < _tables.size();++i)
			{
				Node* cur = _tables[i];
				while (cur)
				{
					Node* tmp = cur;
					cur = cur->_next;

					//头插
					size_t index = _HashFunc(tmp->_key, newTables.size());

					tmp->_next = newTables[index];
					newTables[index] = tmp;
				}

				_tables[i] = NULL;
			}

			_tables.swap(newTables);
		}
	}

	
	void Swap(Table &other)
	{
		_tables.swap(other._tables);
		swap(_size,other._size);
	}
private:
	vector<HashTableNode<K, V>*> _tables;
	size_t _size;//Node底下挂多少数据
};


void TestHashBucketTable()
{
	HashTable<int, int> ht(20);
	ht.Insert(1, 14);
	ht.Insert(2, 12);
	ht.Insert(3, 21);
	ht.Insert(4, 11);
	ht.Print();

	//删除remove
	/*ht.Remove(1);
	ht.Print();*/

	//测试拷贝构造
	HashTable<int, int> other(ht);
	other.Print();
	
	//find函数
	/*HashTableNode<int,int>* ret = ht.Find(1);
	if (ret)
	{
		cout<<"the key is exist: "<<ret->_key<<" "<<ret->_value<<endl;
	}
	else
	{
		cout<<"it is not exist"<<endl;
	}*/
}
}
//哈希桶,基于key-value+仿函数的实现
namespace HASHBUCKET
{
	template<class K, class V>
	struct HashTableNode
	{
		K _key;
		V _value;
		HashTableNode<K, V>* _next;

		HashTableNode(const K& key, const V& value)
			:_key(key),
			_value(value),
			_next(NULL)
		{}
	};

	template<class K>
	struct DefaultHashFunc
	{
		size_t operator()(const K& key)
		{
			return key;
		}
	};

	template<>
	struct DefaultHashFunc<string>
	{
		static size_t BKDRHash(const char * str)
		{
			unsigned int seed = 131; // 31 131 1313 13131 131313
			unsigned int hash = 0;
			while (*str)
			{
				hash = hash * seed + (*str++);
			}
			return (hash & 0x7FFFFFFF);
		}
		size_t operator() (const string& key)
		{
			return BKDRHash(key.c_str());
		}
	};
	template<class K, class V,class HashFunc=DefaultHashFunc<K>>
	class HashTable
	{
		typedef HashTableNode<K,V> Node;
		typedef HashTable<K,V,HashFunc> Table;
	public:

		HashTable()
			:_size(0)
		{}
		HashTable(size_t capacity)//capacity最好是素数,这样可以减少哈希冲突。
			:_size(0)
		{

			_tables.resize(_GetNextPrime(capacity));//确保开辟素数大小空间
		}
		~HashTable()
		{
			for (size_t i = 0;i < _tables.size();++i)
			{
				Node* cur = _tables[i];
				while (cur)
				{
					Node*tmp = cur;
					cur = cur->_next;
					delete tmp;
					tmp = NULL;
				}
				_tables[i] = NULL;
			}
			_size = 0;
		}

		HashTable(const Table& other)
			:_size(0)
		{
			Table newTables(other._tables.size());
			newTables._size = other._size;

			for (size_t i = 0;i < other._tables.size();++i)
			{
				Node* cur = other._tables[i];
				Node*& head = newTables._tables[i];

				while (cur)
				{
					//newTables.Insert(cur->_key, cur->_value);

					Node* tmp = new Node(cur->_key, cur->_value);
					tmp->_next = head;
					head = tmp;

					cur = cur->_next;
				}
			}
			this->Swap(newTables);
		}

		/*Table& operator=(Table t)
		{
		_tables.swap(t);
		swap(_size, t._size);

		return _tables;
		}*/
		Table& operator=(Table& t)
		{
			if (this != &t)
			{
				Table tmp(t);
				_tables.swap(t);
				swap(_size, t._size);
			}


			return _tables;
		}

		bool Insert(const K& key, const V& value)
		{
			size_t index = _HashFunc(key, _tables.size());

			//检查是否存在
			Node* cur = _tables[index];
			while (cur)
			{
				if (cur->_key == key)
				{
					return false;
				}
				cur = cur->_next;
			}

			//头插法
			Node* tmp = new Node(key, value);
			tmp->_next = _tables[index];
			_tables[index] = tmp;

			++_size;
			return true;
		}

		Node* Find(const K& key)
		{
			size_t index = _HashFunc(key, _tables.size());

			Node* cur = _tables[index];
			while (cur)
			{
				if (cur->_key == key)
				{
					return cur;
				}
				cur = cur->_next;
			}
			return NULL;
		}
		bool Remove(const K& key)
		{
			size_t index = _HashFunc(key, _tables.size());

			Node* cur = _tables[index];
			if (cur == NULL)
			{
				return false;
			}
			if (cur->_key == key)
			{
				_tables[index] = cur->_next;
				delete cur;
				return true;
			}
			else
			{
				Node* prev = cur;
				cur = cur->_next;
				while (cur)
				{
					if (cur->_key == key)
					{
						prev->_next = cur->_next;
						delete cur;
						return true;
					}
					prev = cur;
					cur = cur->_next;
				}
				return false;
			}
		}
		void Print()
		{
			for (size_t i = 0; i < _tables.size(); ++i)
			{
				printf("tables[%d]->", i);
				Node* cur = _tables[i];
				while (cur)
				{
					cout << "[" << cur->_key << ":" << cur->_value << "]" << "->";
					cur = cur->_next;
				}

				cout << "NULL" << endl;
			}

			cout << endl;
		}
	protected:
		size_t _GetNextPrime(size_t size)
		{
			const int _PrimeSize = 28;
			static const unsigned long _PrimeList[_PrimeSize] =
			{
				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 < _PrimeSize; ++i)
			{
				if (_PrimeList[i] > size)
				{
					return _PrimeList[i];
				}
			}

			return _PrimeList[_PrimeSize - 1];
		}
		size_t _HashFunc(const K& key, size_t capacity)
		{
			return HashFunc()(key) % capacity;
		}
		void _CheckCapacity()
		{
			//负载值为1时增容
			if (_size == _tables.size())
			{
				size_t nextPrime = _GetNextPrime(_size);

				vector<Node*> newTables;
				newTables.resize(nextPrime);

				for (size_t i = 0;i < _tables.size();++i)
				{
					Node* cur = _tables[i];
					while (cur)
					{
						Node* tmp = cur;
						cur = cur->_next;

						//头插
						size_t index = _HashFunc(tmp->_key, newTables.size());

						tmp->_next = newTables[index];
						newTables[index] = tmp;
					}

					_tables[i] = NULL;
				}

				_tables.swap(newTables);
			}
		}


		void Swap(Table &other)
		{
			_tables.swap(other._tables);
			swap(_size, other._size);
		}
	private:
		vector<HashTableNode<K, V>*> _tables;
		size_t _size;//Node底下挂多少数据
	};


	void TestHashBucketTable()
	{
		HashTable<string, string> dict(10);
		dict.Insert("字典", "dict");
		dict.Insert("插入", "Insert");
		dict.Insert("删除", "Remove");
		dict.Insert("查找", "Find,Search");
		dict.Print();

		//删除remove
		/*dict.Remove("字典");
		dict.Print();*/

		//测试拷贝构造
		//HashTable<int, int> other(ht);
		//other.Print();

		//find函数
		HashTableNode<string,string>* ret = dict.Find("插入");
		if (ret)
		{
		cout<<"the key is exist: "<<ret->_key<<" : "<<ret->_value<<endl;
		}
		else
		{
		cout<<"it is not exist"<<endl;
		}

	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值