哈希表实现线性检测(超详细)

哈希表的线性检测:

思路分析:
1.哈希表定义 ----成员定义(private):存储方式(哈希节点的数组)、元素空间的大小、哈希表构造函数
2.哈希表存入的数据类型: 哈希节点:哈希函数需要知道键值,因此键值数据设置成KV函数,同时哈希删除为假删除,因此需要定义状态
3.哈希表的插入(插入哈希节点)
3.1 检查容量
载荷因子大于设置的0.7就扩容(哈希数组的有效元素比上空间大小 _size*10/_ht.size()),或者无空间(哈希数组_ht.size())
扩容大小
开辟新的哈希空间
插入元素,遍历: 如果旧哈希表该节点位置存在,则插入新表
成员(指针位置,有效元素)位置交换
3.2 哈希函数计算位置:插入的值除以整体空间大小
3.3 哈希键值位置元素是否存在,存在且有值,则插入失败,否则位置加加,插入元素元素一定会存储,就会考虑下一个位置,因此判断需要用while,如果插入元素是最后一个元素位置处,就要考虑位置是否可以存储,不能存储,需要回到开头。插入元素(节点):数据、状态
4.位置交换: 成员交换(private)
5.查找元素(节点数据)
5.1.计算元素位置
5.2.判断元素位置是否存在
5.3.存在则判断值是否相等,相等则返回节点位置
5.4存在值不相等判断是否被存到其他位置

6.删除节点元素
6.1 找到元素位置
6.2 判断元素是否存在,存在:有效元素减一,状态置为DELETE

#include
#include
using namespace std;

enum State{ EMPTY, DELETE, EXIST };  //哈希表只能假删除,因此需要定义状态
//创建一个哈希节点
template<class K, class V>
struct Node   //哈希节点
{
	pair<K, V> _kv;   //数据类型为KV模型
	State _state;
};

template<class K, class V>
class HashTable
{
public:
	typedef Node<K, V> Node;  //节点定义为KV模型 创建了一个哈希节点的对象

	HashTable(size_t n = 10)  //初始化一个空的哈希表
		:_ht(n)
		, _size(0)
	{}

	bool insert(const pair<K, V>& kv)
	{
		//1.检查容量
		CheckCapacity();
		//2.计算位置
		int idx = kv.first%_ht.size();
		//3.判断key值是否存在
		while (_ht[idx]._state != EMPTY)
		{
			if (_ht[idx]._state == EXIST&&_ht[idx]._kv.first == kv.first)
			{
				return false;
			}
			idx++;
			if (idx == _ht.size())
			{
				idx = 0;
			}
		}
		//4.插入元素
		_ht[idx]._kv = kv;
		_ht[idx]._state = EXIST;
	}

	void CheckCapacity()
	{
		if (_ht.size() == 0 || _size * 10 / _ht.size() >= 7)
		{
			//容量
			int newC = _ht.size() == 0 ? 10 : 2 * _ht.size();
			//开辟新的哈希空间
			HashTable<K, V> newHt(newC);
			//遍历插入哈希有效元素
			for (int i = 0; i<_ht.size(); ++i)
			{
				if (_ht[i]._state == EXIST)
				{
					newHt.insert(_ht[i]._kv);
				}
			}
			//交换
			Swap(newHt);
		}
	}

	void Swap(HashTable<K, V> ht)
	{
		swap(_ht, ht._ht);
		swap(_size, ht._size);
	}

	Node* Find(const K& key)
	{
		//1.计算元素位置
		int idx = key%_ht.size();
		//2.判断元素位置是否存在
		//3.存在则判断值是否相等,相等则返回节点位置
		//  存在值不相等判断是否被存到其他位置
		while (_ht[idx]._state != EXIST)
		{
			if (_ht[idx]._state == EXIST&&_ht[idx]._kv.first == key)
			{
				return &_ht[idx];
			}
			++idx;
			if (idx == _ht.size())
			{
				idx = 0;
			}
		}
		return nullptr;
	}

	bool erase(const K& key)
	{
		//假删除
		//1.找到元素位置
		Node* node = Find(key);
		//2.节点存在则删除节点,返回true
		if (node){
			--_size;
			node->_state = DELETE;
			return true;
		}
		return false;
	}

	bool Empty() const
	{
		return _size == 0;
	}


	size_t Size() const
	{
		return _size;
	}

private:
	vector<Node> _ht;    //类型为哈希节点的数组: 存储哈希数据
	size_t _size;        //有效元素个数
};

void test()
{
	HashTable<int, int> ht;
	ht.insert(make_pair(1, 1));
	ht.insert(make_pair(14, 14));
	ht.insert(make_pair(16, 16));
	ht.insert(make_pair(11, 11));
	ht.insert(make_pair(14, 140));
	ht.insert(make_pair(2, 1));
	ht.insert(make_pair(3, 14));
	ht.insert(make_pair(5, 16));
	ht.insert(make_pair(7, 11));
	ht.insert(make_pair(8, 140));
	ht.insert(make_pair(13, 1));

	cout << ht.Find(11) << endl;
}

int main()
{
	test();
	system("pause");
	return 0;
}

你可能感兴趣的:(C++,c++)