可以实现快速定位查找数据

思想一:开一个适当大小的数组,讲需要存入的数据%上数组的_capacity的到的数作为他存放的位置,如果这个位置被占了,则在他的下一个位置存放数据(不会找不到空位置,下面会说到)。

思想二:存放在数组上的是一个结构体,结构体包含一个索引值Key,存储值Value,和一个存储状态(枚举类型,EXIST,EMPTY,DELETE)可以使用这三种状态进行判断和懒人删除法(不用清除数据,设置为DELETE状态即可)。

思想三:开辟空间的问题,初始空间经过资料查询,开一个大小为53(质数)大小空间,负载因子为0.7左右时便进行容量的扩充,这时需要进行重新的存储,因为空间变了所以位置变了。

*负载因子:已使用空间除以总空间大小。

#include  <iostream>
#include<vector>
using namespace std;
enum Signtable
{
	EXIST,
	EMPTY,
	DELETE
};
template<class T,class K>
struct Package
{
	T _myValue;
	K _key;
	Signtable _sign;
};

template <class T, class K> 
class HashTable
{
public:
	HashTable()
		:_capacity(0),
		_size(0)
	{
		_Newcapacity();
	}
	void Insert(T t,K k)
	{
		double j = (double)_size / (double)_capacity;
		 if (j>= 0.7)
		{
			_Newcapacity();
		}
			size_t key = _returnkey(k);
			while (_hashTable[key]._sign == EXIST)
			{
				key++;
				if (key > _capacity - 1)
				{
					key = 0;
				}
			}
			_hashTable[key]._myValue = t;
			_hashTable[key]._key = k;
			_hashTable[key]._sign = EXIST;
			_size++;
	}
	bool Find(K k, T t)
	{
		size_ flag = 0;
		size_t key = _returnkey(k);
		while (_hashTable[key]._key != EMPTY)
		{
			if (_hashTable[key]._myValue == t)
			{
				return  true;
			}
			key++;
			if (key > _capacity - 1)
			{
				key = 0;
				flag++;
			}
			if (flag > 1)
			{
				break;
			}
		}
		return false;
		
	}
	bool Remove(K k,T t)
	{
		size_t flag = 0;
		size_t key = _returnkey(k);
		while (_hashTable[key]._key != EMPTY)
		{
			if (_hashTable[key]._myValue == t&&_hashTable[key]._sign==EXIST)
			{
				_hashTable[key]._sign = DELETE;
				return  true;
			}
			key++;
			if (key > _capacity - 1)
			{
				key = 0;
				flag ++ ;
			}
			if (flag > 1)
			{
				break;
			}
			return false;
		}
	}
protected:
	void _Newcapacity()
	{
		if (_capacity == 0)
		{
			_hashTable.resize(10);
			_capacity = 10;
			size_t i = 0;
			for (i = 0; i < _capacity; i++)
			{
				_hashTable[i]._myValue = 0;
				_hashTable[i]._key = 0;
				_hashTable[i]._sign = EMPTY;

			}
		}
		else
		{
			HashTable<T,K> newTable;
			newTable._hashTable.resize(_capacity * 2);
			newTable._capacity = _capacity*2;
			for (size_t i = 0; i < newTable._capacity; i++)
			{
				newTable._hashTable[i]._myValue = 0;
				newTable._hashTable[i]._key = 0;
				newTable._hashTable[i]._sign = EMPTY;

			}
			size_t k = 0;
			while (k<_capacity)
			{
				if (_hashTable[k]._sign != EMPTY)
				{
					newTable.Insert(_hashTable[k]._myValue, _hashTable[k]._key);
				}
				k++;
			}
			newTable._size = _size;;;;;
			*this = newTable;
		}
	}
	size_t _returnkey(K k)
	{
		return k%_capacity;
	}
private:
	vector<Package<T, K>> _hashTable;
	size_t _capacity;
	size_t _size;
};

void Test1()
{
	HashTable<int, int> hash;
	hash.Insert(2, 2);
	hash.Insert(3, 2);
	hash.Insert(4, 2);
	hash.Insert(4, 2);
	hash.Insert(3, 2);
	hash.Insert(4, 2);
	hash.Insert(4, 2);
	hash.Insert(2, 2);
	hash.Insert(3, 2);
	hash.Insert(4, 2);
	hash.Insert(4, 2);
	cout << hash.Remove(4, 2) << endl;
	cout << hash.Find(4, 2) << endl;
}

int main()
{
	Test1();
	return 0;
}