微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

【数据结构】哈希表

HashTable-散列表/哈希表,是根据关键字(key)而直接访问在内存存储位置的数据结构。
它通过一个关键值的函数将所需的数据映射到表中的位置来访问数据,这个映射函数叫做散列函数,存放记录的数组叫做散列表。
构造哈希表的几种方法
1. 直接定址法--取关键字的某个线性函数为散列地址,Hash(Key)= Key 或 Hash(Key)= A*Key + B,A、B为常数。
2. 除留余数法--取关键值被某个不大于散列表长m的数p除后的所得的余数为散列地址。Hash(Key)= Key % P。
3. 平方取中法
4. 折叠法
5. 随机数法

6. 数学分析法

这里实现除留余数法构造的哈希表

除留余数函数

size_t _HashFunc(const K& key)
	{
		return key%_table.size();
	}

实现哈希表、
#include<iostream>
#include <cstdlib>
#include <vector>
using namespace std;
enum Status
{
	EMPTY,EXIST,DELETE,};
template<class K,class V>
struct HashTableNode
{
	K _key;
	V _value;
	Status _status;
	HashTableNode(const K& key=K(),const V& value=V())
		:_key(key),_value(value),_status(EMPTY)
	{}
};
template<class K,class V>
class HashTable
{
	typedef HashTableNode<K,V> Node;
public:
	HashTable()
		:_size(0)
	{
		_table.resize(_GetNextPrime(0));
	}
	~HashTable()
	{}
	bool Insert(const K& key,const V& value)
	{
		Checksize();
		size_t index=_HashFunc(key);
		while (_table[index]._status==EXIST)
		{
			if(_table[index]._key==key)
				return false;
			++index;
			if(index==_table.size())
				index=0;
		}
		_table[index]._key=key;
		_table[index]._value=value;
		_table[index]._status=EXIST;
		_size++;
		return true;
	}
	Node* Find(const K& key)
	{
		if(_table.empty())
		{
			return NULL;
		}
		for (size_t i=0;i<_table.size();i++)
		{
			if(_table[i]._status==EXIST&&_table[i]._key==key)
				return &_table[i];
			else
				continue;
		}
		return NULL;
	}
	bool Remove(const K& key)
	{
		if (_table.empty())
		{
			return false;
		}
		Node* del=Find(key);
		if(del->_status==EXIST)
		{
			del->_status=DELETE;
			return true;
		}
		else
			return false;
	}
	void display()
	{
		if(_table.size()==0)
		{
			return;
		}
		for (size_t i=0;i<_table.size();i++)
		{
			cout<<" key:"<<_table[i]._key<<" value:"<<_table[i]._value<<" status:"<<_table[i]._status<<endl;
		}
		cout<<endl;
	}
protected:
	size_t _HashFunc(const K& key)
	{
		return key%_table.size();
	}
	void Checksize()
	{
		if(_table.size()==0||_size*10/_table.size()>=8)
		{
			size_t newsize=_GetNextPrime(_table.size());
			HashTable hash;
			hash._table.resize(newsize);
			for (size_t i=0;i<_table.size();i++)
			{
				if(_table[i]._status==EXIST)
				{
					hash.Insert(_table[i]._key,_table[i]._value);
				}
			}
			this->Swap(hash);
		}
	}
	size_t _GetNextPrime(size_t num)
	{
		const int _PrimeSize=28;
		static const unsigned long _PrimeList[_PrimeSize]=
		{
			53ul,97ul,193ul,389ul,769ul,1543ul,3079ul,6151ul,12289ul,24593ul,49157ul,98317ul,1996613ul,391241ul,786433ul,1572869ul,3145739ul,6291469ul,12582917ul,25165843ul,50331653ul,100663319ul,201326611ul,402653189ul,805306457ul,1610612741ul,3221225473ul,429496729ul
		};
		for (size_t i=0;i<_PrimeSize;i++)
		{
			if(_PrimeList[i]>num)
				return _PrimeList[i];
		}
		return 429496729ul;
	}
	void Swap(HashTable<K,V>& hs)
	{
		_table.swap(hs._table);
		swap(_size,hs._size);
	}
protected:
	vector<Node> _table;
	size_t _size;
};
void testHash()
{
	HashTable<int,int> hash;
	for (size_t i=0;i<20;i++)
	{
		hash.Insert(i,i);
	}
	for (size_t i=10;i<30;i++)
	{
		hash.Insert(i,i);
	}
	hash.display();
	hash.Remove(3);
	hash.Remove(7);
	hash.display();
}

原文地址:https://www.jb51.cc/datastructure/382415.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐