处理哈希冲突的闭散列方法-线性探测

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了处理哈希冲突的闭散列方法-线性探测相关的知识,希望对你有一定的参考价值。

 说到哈希冲突,就必须谈到哈希函数了。

  • 什么时候哈希函数

          哈希冲突函数hv(i),用于在元素i发生哈希冲突时,将其映射至另一个内存位置。

  • 什么是哈希冲突

         哈希冲突即关键字不同的元素被映射到了同一个内存位置,包括由同义词冲突和非同义词冲突。

 处理哈希冲突的方法很多,这里浅谈一下处理哈希冲突的闭散列方法:

  • 线性探测

    如下图所示

技术分享

  在上图中,这里key取8。

实现线性探测代码:
#pragma once
#include<string>
enum Status
{
	EXIST,
	EMPTY,
	DELETE,
};
//如果是数据类型,直接返回数据,定位位置
template<class T>
struct DataType
{
	long long operator()(const T&key)
	{
		return key;
	}
};
//如果是字符串类型,求出字符串ASCII和,根据求出的和定位位置
template<class T>
struct StringType
{
	long long operator()(const string&key)
	{
		long long size = 0;
		for (size_t i = 0; i < key.size(); i++)
		{
			size = size + key[i];
		}
		return size;
	}

};
//定义的哈希类
template<class T,template<class T> class HashFuncer=DataType>
//class HashFuncer = DataType<T>
class HashTable
{
public:
	HashTable()
		:_tables(NULL)
		, _status(NULL)
		, _size(0)
		, _capacity(0)
	{}
	HashTable(const size_t size)
		:_tables(new T[size])
		, _status(new Status[size])
		, _size(0)
		, _capacity(size)
	{
		for (size_t i = 0; i < size; i++)
		{
			_status[i] = EMPTY;
		}
	}
	HashTable(const HashTable<T,HashFuncer>&ht)
	{
		HashTable<T,HashFuncer> tmp(ht._capacity);
		for (size_t i = 0; i < ht._capacity; i++)
		{
			if (ht._status[i] != EMPTY)
			{
				tmp._status[i] = ht._status[i];
				tmp._tables[i] = ht._tables[i];
			}
		}
		tmp._size = ht._size;
		tmp._capacity = ht._capacity;
		this->Swap(tmp);
	}
	~HashTable()
	{
		if (_tables)
		{
			delete[] _tables;
			delete[] _status;
		}
		_size = 0;
		_capacity = 0;
	}
	HashTable<T, HashFuncer>& operator=(const HashTable<T, HashFuncer> &ht)
	{
		if (_tables != ht._tables)
		{
			HashTable<T, HashFuncer> ht1(ht);
			/*HashTable<T, HashFuncer> ht1(ht._capacity);
			for (size_t i = 0; i < ht._capacity; i++)
			{
				if (ht._status[i] != EMPTY)
				{
					ht1._tables[i] = ht._tables[i];
					ht1._status[i] = ht._status[i];
				}
			}
			ht1._size = ht._size;*/
			this->Swap(ht1);
		}
		return *this;
	}
	bool Insert(const T&key)
	{
		_CheckCapacity();
		size_t index = _HashFunc(key);
		while (_status[index] == EXIST)
		{
			if (_tables[index] == key)
			{
				return false;
			}
			++index;
			if (index == _capacity)
			{
				index = 0;
			}
		}
		_status[index] = EXIST;
		_tables[index] = key;
		_size++;
		return true;
	}
	size_t Find(const T&key)
	{
		size_t index = _HashFunc(key);
		while (_status[index] != EMPTY)
		{
			if (_tables[index] == key&&_status[index] != DELETE)
			{
				return index;
			}
			++index;
			if (index == _capacity)
			{
				index = 0;
			}
		}
		return -1;
	}
	bool Remove(const T&key)
	{
		int index = Find(key);
		if (index != -1)
		{
			_status[index] = DELETE;
			return true;
		}
		return false;
	}
	void _CheckCapacity()//载荷因子
	{
		if (_size * 10 >= _capacity * 7)
		{
			HashTable<T,HashFuncer> tmp(2 * _capacity+3);
			for (size_t i = 0; i < _capacity; ++i)
			{
				if (_status[i] != EMPTY)
				{
					tmp.Insert(_tables[i]);
				}
			}
			this->Swap(tmp);
		}
	}
	void PrintTables()
	{
		for (size_t i = 0; i < _capacity; ++i)
		{
			if (_status[i] == EXIST)
			{
				printf("[%d]:E->", i);
				cout << _tables[i];
			}
			else if (_status[i] == DELETE)
			{
				printf("[%d]:D->", i);
				cout << _tables[i];
			}
			else if (_status[i] == EMPTY)
			{
				printf("[%d]:N->NONE", i);
			}
			cout << endl;
		}
		cout << endl;
	}
	void Swap(HashTable<T,HashFuncer> &ht)
	{
		swap(_tables, ht._tables);
		swap(_status, ht._status);
		swap(_size, ht._size);
		swap(_capacity, ht._capacity);
	}
	size_t _HashFunc(const T&key)
	{
		HashFuncer<T> hf;
		return hf(key)%_capacity;
	}
protected:
	T *_tables;
	Status *_status;
	size_t _size;
	size_t _capacity;
};


本文出自 “学习记录” 博客,转载请与作者联系!

以上是关于处理哈希冲突的闭散列方法-线性探测的主要内容,如果未能解决你的问题,请参考以下文章

线性探测-闭散列

哈希结构介绍及实现(线性探测)——闭散列解决哈希冲突

hash哈希

hash哈希

hash哈希

C++ 哈希