中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

哈希表/散列表

發布時間:2020-07-20 13:14:49 來源:網絡 閱讀:330 作者:下一個明天 欄目:編程語言


哈希表/散列表,是根據關鍵字(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 <iostream>
#include <string>
using namespace std;

enum State
{
	EMPTY,
	DELETE,
	EXITS,
};
//以key形式實現線性探測
template <class T>
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<T>& ht) //拷貝構造
	{
		_tables = new T[ht._capacity];
		_states = new State[ht._capacity];
		for(size_t i=0;i<ht._capacity;++i)
		{
			if(ht._tables[i] != EMPTY)
			{
				_tables[i] = ht._tables[i];
				_states[i] = ht._states[i];
			}		
		}
		_capacity = ht._capacity;
		_size = ht._size;
	}

	//HashTable<T>& operator=(const HashTable<T>& ht)  //賦值操作符重載
	//{
	//	if(this != &ht)
	//	{
	//		delete[] _tables;
	//		delete[] _states;
	//		_tables = new T[ht._capacity];
	//		_states = new State[ht._capacity];
	//		for(size_t i=0;i<ht._capacity;++i)
	//		{
	//			if(ht._tables[i] != EMPTY)
	//			{
	//				_tables[i] = ht._tables[i];
	//				_states[i] = ht._states[i];
	//			}		
	//		}
	//		_capacity = ht._capacity;
	//		_size = ht._size;
	//	}
	//	return *this;
	//}


	//現代寫法
	HashTable<T>& operator=(HashTable<T> 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<T> tmp(2*_capacity);
			for(size_t i=0;i<_capacity;++i)
			{
				if(_states[i] == EXITS)
				{
					tmp.Insert(_tables[i]);
				}
			}
			Swap(tmp);
		}	
	}
	
	void Swap(HashTable<T>& 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<<endl;
	}
private:
	T* _tables; //哈希表
	State* _states; //狀態表
	size_t _size; //數據的個數
	size_t _capacity; //容量
};


//以key形式實現二次探測
//enum State
//{
//	EMPTY,
//	DELETE,
//	EXITS,
//};
//template <class T>
//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<ht._capacity;++i)
//		{
//			if(ht._tables[i] != EMPTY)
//			{
//				_tables[i] = ht._tables[i];
//				_states[i] = ht._states[i];
//			}		
//		}
//		_capacity = ht._capacity;
//		_size = ht._size;
//	}
//
//	HashTableSecond& operator=(const HashTableSecond& ht)  //賦值操作符重載
//	{
//		if(this != &ht)
//		{
//			delete[] _tables;
//			delete[] _states;
//			_tables = new T[ht._capacity];
//			_states = new State[ht._capacity];
//			for(size_t i=0;i<ht._capacity;++i)
//			{
//				if(ht._tables[i] != EMPTY)
//				{
//					_tables[i] = ht._tables[i];
//					_states[i] = ht._states[i];
//				}		
//			}
//			_capacity = ht._capacity;
//			_size = ht._size;
//		}
//		return *this;
//	}
//
//public:
//	bool Insert(const T& key) //插入
//	{
//		_CheckCapacity();
//		size_t start = HashFunc(key);
//		size_t index = start;
//		size_t i = 1;
//		while(_states[index] == EXITS)  
//		{
//			if(_tables[index] == key)
//			{
//				return false;
//			}
//			index = start + i * i;
//			++i;
//			index %= _capacity;
//		}
//		_tables[index] = key;
//		_states[index] = EXITS;
//		++_size;
//		return true;
//	}
//	bool 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)
//			{
//				return true;
//			}
//			index = start + i * i;
//			++i;
//			index %= _capacity;
//		}
//		return false;
//	}
//	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)
//			{
//				_states[index] = DELETE;
//				return true;
//			}
//			index = start + i * i;
//			++i;
//			index %= _capacity;
//		}
//		return false;
//	}
//public:
//	size_t HashFunc(const T& key)  //哈希函數
//	{
//		return key%10;
//	}
//
//	void _CheckCapacity()  //檢測容量
//	{
//		if(_size*10 % _capacity == 7)
//		{
//			HashTableSecond<T> tmp(2*_capacity);
//			for(size_t i=0;i<_capacity;++i)
//			{
//				if(_states[i] == EXITS)
//				{
//					tmp.Insert(_tables[i]);
//				}
//			}
//			Swap(tmp);
//		}	
//	}
//	
//	void Swap(HashTableSecond<T>& 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<<endl;
//	}
//private:
//	T* _tables; //哈希表
//	State* _states; //狀態表
//	size_t _size; //數據的個數
//	size_t _capacity; //容量
//};


//以key/value形式實現二次探測,支持字典查詢
//enum State
//{
//	EMPTY,
//	DELETE,
//	EXITS,
//};

template <class T,class K>
struct HashTableNode //節點
{
	T key;
	K value;
};
template <class T>
struct __HashFunc    //重載()
{
	size_t operator()(const T& key)
	{
		return key;
	}
};

template<>
struct __HashFunc<string>   //特化
{
	size_t operator()(const string& key)
	{
		size_t hash = 0;
		for(size_t i=0;i<key.size();++i)
		{
			hash += key[i];
		}
		return hash;
	}	
};

template <class T,class K,class HashFunc = __HashFunc<T> >
class HashTableSecond
{
public:
	HashTableSecond(size_t capacity = 10)
		:_tables(new HashTableNode<T,K>[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<T,K>* 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<T,K> 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<T,K>& 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<<endl;
	}
private:
	HashTableNode<T,K>* _tables; //哈希表
	State* _states; //狀態表
	size_t _size; //數據的個數
	size_t _capacity; //容量
};
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

香河县| 东兰县| 伊川县| 仪陇县| 久治县| 江津市| 公主岭市| 贵溪市| 西畴县| 德钦县| 侯马市| 湘潭市| 天柱县| 博客| 依安县| 乳山市| 兴仁县| 台南县| 五原县| 明水县| 吉林省| 林西县| 特克斯县| 泾川县| 蕉岭县| 恩施市| 新巴尔虎右旗| 东方市| 龙川县| 包头市| 永德县| 大同市| 开封市| 丹凤县| 长海县| 全州县| 乐都县| 二连浩特市| 潞西市| 英吉沙县| 开原市|