资讯

精准传达 • 有效沟通

从品牌网站建设到网络营销策划,从策略到执行的一站式服务

哈希表/散列表-创新互联

哈希表/散列表,是根据关键字(key)直接访问在内存存储位置的数据结构。

站在用户的角度思考问题,与客户深入沟通,找到武川网站设计与武川网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:网站设计制作、做网站、企业官网、英文网站、手机端网站、网站推广、域名注册雅安服务器托管、企业邮箱。业务覆盖武川地区。

构造哈希表的常用方法:

  1. 直接地址法---取关键字的某个线性函数为散列地址,Hash(Key) = Key或Hash(key) = A*Key + B,

    A,B为常数。

  2. 除留余数法---取关键值被某个不大于散列表长m的数p除后的所得的余数为散列地址。

    Hash(key) = key % p。

  若采用直接地址法(Hash(Key) = Key)存在一定的缺陷。

  当Key值特别大时,而Key之前的数很少,就会造成空间浪费。大多时候采取除留余数法。

  哈希冲突/哈希碰撞

  不同的Key值经过哈希函数Hash(Key)处理以后可能产生相同的哈希地址,我们称这种情况为哈希冲突。任何的散列函数都不能避免产生冲突。

 散列表的载荷因子定义为a = 填入表中元素的个数/散列表的长度

 载荷因子越大,冲突的可能性就越大。

 解决冲突的办法:

 (1)线性探测

哈希表/散列表

 (2)二次探测

哈希表/散列表

#pragma once
#include 
#include 
using namespace std;

enum State
{
	EMPTY,
	DELETE,
	EXITS,
};
//以key形式实现线性探测
template 
class HashTable
{
public:
	HashTable(T capacity = 10)
		:_tables(new T[capacity])
		,_states(new State[capacity])
		,_capacity(capacity)
		,_size(0)
	{
		for(size_t i=0;i < _capacity;++i)
		{
			_states[i] = EMPTY;
		}
	}

	~HashTable()
	{
		delete[] _tables;
		delete[] _states;
		_tables = NULL;
		_states = NULL;
	}

	HashTable(const HashTable& ht) //拷贝构造
	{
		_tables = new T[ht._capacity];
		_states = new State[ht._capacity];
		for(size_t i=0;i& operator=(const HashTable& ht)  //赋值操作符重载
	//{
	//	if(this != &ht)
	//	{
	//		delete[] _tables;
	//		delete[] _states;
	//		_tables = new T[ht._capacity];
	//		_states = new State[ht._capacity];
	//		for(size_t i=0;i& operator=(HashTable ht)  //赋值操作符重载
	{
		this->Swap(ht);
		return *this;
	}

public:
	bool Insert(const T& key) //插入
	{
		_CheckCapacity();
		size_t index = HashFunc(key);
		while(_states[index] == EXITS) 
		{
			if(_tables[index] == key)  //冗余
			{
				return false;
			}
			++index;
			if(index == _capacity)  //到达哈希表尾部
			{
				index = 0;
			}
		}
		_tables[index] = key;
		_states[index] = EXITS;
		++_size;
		return true;
	}
	bool Find(const T& key)  //查找
	{
		size_t index = HashFunc(key);
        size_t start = index;
		while(_states[index] == EXITS)
		{
			if(_tables[index] == key)  
			{
				return true;
			}
			++index;
			if(index == _capacity)
			{
				index = 0;
			}
            if(start == index)   //哈希表查完
            {
               return false;
            }
		}
		return false;
	}
	bool Remove(const T& key)  //删除
	{
		size_t index = HashFunc(key);
		size_t start = index;
		while(_states[index] == EXITS)
		{
			if(_tables[index] == key)
			{
				_states[index] = DELETE;
				return true;
			}
			++index;
			if(index == _capacity)  //到达哈希表的尾部
			{
				index = 0;
			}
            if(start == index)  //哈希表查完
            {
               return false;
            }
		}
		return false;
	}
public:
	size_t HashFunc(const T& key)  //哈希函数
	{
		return key%10;
	}

	void _CheckCapacity()  //检查容量
	{
		if(_size*10 % _capacity == 7)  //载荷因子
		{
			HashTable tmp(2*_capacity);
			for(size_t i=0;i<_capacity;++i)
			{
				if(_states[i] == EXITS)
				{
					tmp.Insert(_tables[i]);
				}
			}
			Swap(tmp);
		}	
	}
	
	void Swap(HashTable& ht)
	{
		swap(_tables,ht._tables);
		swap(_states,ht._states);
		swap(_size,ht._size);
		swap(_capacity,ht._capacity);
	}

	void Print()
	{
		for(size_t i=0;i<_capacity;++i)
		{
			cout<<"["<<_states[i]<<","<<_tables[i]<<"]"<<" ";
		}
		cout<
//class HashTableSecond
//{
//public:
//	HashTableSecond(T capacity = 10)
//		:_tables(new T[capacity])
//		,_states(new State[capacity])
//		,_capacity(capacity)
//		,_size(0)
//	{
//		for(size_t i=0;i < _capacity;++i)
//		{
//			_states[i] = EMPTY;
//		}
//	}
//
//	~HashTableSecond()
//	{
//		delete[] _tables;
//		delete[] _states;
//		_tables = NULL;
//		_states = NULL;
//	}
//
//	HashTableSecond(const HashTableSecond& ht) //拷贝构造
//	{
//		_tables = new T[ht._capacity];
//		_states = new State[ht._capacity];
//		for(size_t i=0;i tmp(2*_capacity);
//			for(size_t i=0;i<_capacity;++i)
//			{
//				if(_states[i] == EXITS)
//				{
//					tmp.Insert(_tables[i]);
//				}
//			}
//			Swap(tmp);
//		}	
//	}
//	
//	void Swap(HashTableSecond& ht)
//	{
//		swap(_tables,ht._tables);
//		swap(_states,ht._states);
//		swap(_size,ht._size);
//		swap(_capacity,ht._capacity);
//	}
//
//	void Print()
//	{
//		for(size_t i=0;i<_capacity;++i)
//		{
//			cout<<"["<<_states[i]<<","<<_tables[i]<<"]"<<" ";
//		}
//		cout<
struct HashTableNode //节点
{
	T key;
	K value;
};
template 
struct __HashFunc    //重载()
{
	size_t operator()(const T& key)
	{
		return key;
	}
};

template<>
struct __HashFunc   //特化
{
	size_t operator()(const string& key)
	{
		size_t hash = 0;
		for(size_t i=0;i >
class HashTableSecond
{
public:
	HashTableSecond(size_t capacity = 10)
		:_tables(new HashTableNode[capacity])
		,_states(new State[capacity])
		,_capacity(capacity)
		,_size(0)
	{
		for(size_t i=0;i < _capacity;++i)
		{
			_states[i] = EMPTY;
		}
	}
	~HashTableSecond()
	{
		delete[] _tables;
		delete[] _states;
		_tables = NULL;
		_states = NULL;
	}

public:
	bool Insert(const T& key,const K& value)  //插入
	{
		_CheckCapacity();
		size_t start = __HashFunc(key);
		size_t index = start;
		size_t i = 1;
		while(_states[index] == EXITS)  
		{
			if(_tables[index].key == key)
			{
				return false;
			}
			index = start + i * i;
			++i;
			index %= _capacity;
		}
		_tables[index].key = key;
		_tables[index].value = value;
		_states[index] = EXITS;
		++_size;
		return true;
	}
	HashTableNode* Find(const T& key)  //查找
	{
		size_t start = __HashFunc(key);
		size_t index = start;
		size_t i = 1;
		while(_states[index] == EXITS)
		{
			if(_tables[index].key == key)
			{
				return &(_tables[index]);
			}
			index = start + i * i;
			++i;
			index %= _capacity;
		}
		return NULL;
	}

	bool Remove(const T& key)  //删除
	{
		size_t start = __HashFunc(key);
		size_t index = start;
		size_t i = 1;
		while(_states[index] == EXITS)
		{
			if(_tables[index].key == key)
			{
				_states[index] = DELETE;
				return true;
			}
			index = start + i * i;
			++i;
		}
		return false;
	}
public:
	size_t __HashFunc(const T& key)  //哈希函数
	{
		HashFunc hfun;
		return hfun(key)%_capacity;
	}
 
	void _CheckCapacity()  //检测容量
	{
		if(_size*10 % _capacity == 7)
		{
			HashTableSecond tmp(2*_capacity);
			for(size_t i=0;i<_capacity;++i)
			{
				if(_states[i] == EXITS)
				{
					tmp.Insert(_tables[i].key,_tables[i].value);
				}
			}
			Swap(tmp);
		}	
	}
	
	void Swap(HashTableSecond& ht)
	{
		swap(_tables,ht._tables);
		swap(_states,ht._states);
		swap(_size,ht._size);
		swap(_capacity,ht._capacity);
	}

	void Print()
	{
		for(size_t i=0;i<_capacity;++i)
		{
			cout<<"["<<_tables[i].key<<","<<_tables[i].value<<"]"<<" ";
		}
		cout<* _tables; //哈希表
	State* _states; //状态表
	size_t _size; //数据的个数
	size_t _capacity; //容量
};

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


文章名称:哈希表/散列表-创新互联
当前地址:http://cdkjz.cn/article/dpphpe.html
多年建站经验

多一份参考,总有益处

联系快上网,免费获得专属《策划方案》及报价

咨询相关问题或预约面谈,可以通过以下方式与我们联系

大客户专线   成都:13518219792   座机:028-86922220