故数据存储下标为   伪代码:&"/>

哈希表解决冲突法(二次探测)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了哈希表解决冲突法(二次探测)相关的知识,希望对你有一定的参考价值。

技术分享

故数据存储下标为

     伪代码:

                     1. //index=_HashFunc(key);

                        //++i;

//index+=(2*i-1);

                        size_t _HashFunc(const K& key)

                        {

                              return key%_capacity;

                         }

     2.//index=_HashFunc(key,++i);

                       size_t _HashFunc(const K& key,size_t i)

                       {     

                            return (key+i*i)%_capacity;

                        }

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

enum Status
{
	EXIST,
	EMPTY,
	DELETE
};
template<class K>
class HashTable
{
public:
	HashTable(int capacity)
		:_table(new K[capacity])
		, _size(0)
		, _capacity(capacity)
		, _statu(new Status[capacity])
	{
		memset(_table, 0, sizeof(K)*capacity);
		for (int i = 0; i < capacity; ++i)
		{
			_statu[i] = EMPTY;
		}
	}
	HashTable(const HashTable& hb)
		:_table(new K[hb._capacity])
		, _capacity(hb._capacity)
		, _size(0)
		, _statu(new Status[_capacity])
	{
		memset(_table, 0, sizeof(K)*_capacity);
		for (int i = 0; i < _capacity; ++i)
		{
			_statu[i] = EMPTY;
		}

		for (int i = 0; i < _capacity; ++i)
		{
			if (hb._statu[i] == EXIST)
			{
				this->Insert(hb._table[i]);
			}
		}
	}
	HashTable& operator=(HashTable ht)
	{
		this->_Swap(ht);
		return *this;
	}
	~HashTable()
	{
		if (_table)
			delete[] _table;
		if (_statu)
			delete[] _statu;
		_capacity = _size = 0;
	}
	bool Insert(const K& key)
	{
		if (_size * 10 / _capacity >= 7)//负载因子最好在0.7到0.8
		{
			size_t newCapacity = _capacity * 2;
			HashTable<K> tmp(newCapacity);
			for (int i = 0; i < _capacity; ++i)
			{
				if (_statu[i] == EXIST)
				{
					tmp.Insert(_table[i]);
				}
			}
			this->_Swap(tmp);//自定义
		}
		
		int i = 0;
		size_t index = _HashFunc(key,i);
		size_t begin = index;
		do
		{
			if (_statu[index] == EMPTY||_statu[index]==DELETE)
				break;
			if (_statu[index] == EXIST&&_table[index] == key)
			{
				return false;
			}
			index = _HashFunc(key, ++i);
			if (index == _capacity)
				index = 0;
		} while (begin!=index);
		if (_statu[index] == EXIST)
			return false;
		_table[index] = key;
		_statu[index] = EXIST;
		++_size;
		return true;
	}
	bool Find(const K& key)
	{
		int i = 0;
		size_t index = _HashFunc(key,i);
		while (_statu[index] != EMPTY)
		{
			if (_statu[index] == EXIST&&_table[index] == key)
			{
				return true;
			}
			index=_HashFunc(key,++i);
			if (++index == _capacity)
				index = 0;
		}
		return false;
	}
	//懒删除
	bool  Remove(const K& key)
	{
		int i = 0;
		size_t index = _HashFunc(key,0);
		while (_statu[index] != EMPTY)
		{
			if (_statu[index] == EXIST&&_table[index] == key)
			{
				_statu[index] = DELETE;
				--_size;
				return true;
			}
			index = _HashFunc(key,++i);
			if (++index == _capacity)
				index = 0;
		}
		return false;
	}
	void Print()
	{
		for (int i = 0; i < _capacity; ++i)
		{
			printf("%d:%d-->", _table[i], _statu[i]);
		}
		cout << endl;
	}
protected:
	void _Swap(HashTable& ht)
	{
		swap(_table, ht._table);
		swap(_size, ht._size);
		swap(_capacity, ht._capacity);
		swap(_statu, ht._statu);
	}
	size_t _HashFunc(const K& key,size_t i)
	{
		return (key+i*i)%_capacity;
	}
protected:
	K* _table;
	size_t _size;
	size_t _capacity;
	Status* _statu;
};
void Test2()
{
	HashTable<int> ht(10);
	ht.Insert(89);
	ht.Insert(18);
	ht.Insert(49);
	ht.Insert(58);
	ht.Insert(9);
	ht.Print();

	HashTable<int> hb(10);
	hb.Insert(1);
	hb.Insert(2);
	hb.Insert(3);
	hb.Insert(4);
	hb.Insert(9);
	hb.Print();

	HashTable<int> h(ht);
	h.Print();

	h = hb;
	h.Print();
}


本文出自 “小止” 博客,请务必保留此出处http://10541556.blog.51cto.com/10531556/1753186

以上是关于哈希表解决冲突法(二次探测)的主要内容,如果未能解决你的问题,请参考以下文章

哈希表原理及如何避免键值冲突法?

哈希表-线性探测插入删除

1078 Hashing (25 分)难度: 一般 / 知识点: 哈希表二次探测法

室友竟只在2021的最后一天就学会了哈希表

Java解决Hash(散列)冲突的四种方法--开放地址法(线性探测,二次探测,伪随机探测)链地址法再哈希建立公共溢出区

哈希表处理冲突的几种方式