雜湊表/散列表

來源:互聯網
上載者:User

標籤:雜湊


雜湊表/散列表,是根據關鍵字(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)線性探測           

650) this.width=650;" src="http://s5.51cto.com/wyfs02/M00/80/E8/wKiom1dEOC3AwU7_AAAgmRPnoLI040.png" style="float:none;" title="1.PNG" alt="wKiom1dEOC3AwU7_AAAgmRPnoLI040.png" />

 (2)二次探測

650) this.width=650;" src="http://s5.51cto.com/wyfs02/M01/80/E8/wKiom1dEOC3hxQKcAAAhTSAbGWM948.png" style="float:none;" title="2.PNG" alt="wKiom1dEOC3hxQKcAAAhTSAbGWM948.png" />

#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; //容量};

本文出自 “一起去看星星” 部落格,轉載請與作者聯絡!

雜湊表/散列表

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.