生活随笔
收集整理的這篇文章主要介紹了
                                
哈希表---开链法解决哈希冲突
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
 
                                
                            
                            
                             上篇文章已經寫過構造哈希表時用開放定址法解決哈希沖突,這次我就來寫寫這個開鏈法解決哈希沖突的問題!
 
 一、結點定義
 
 我們已經知道開鏈法大概是一種什么結構了,(如果不知道,這里有講哦點我點我)顯而易見,實現哈希桶的話我們就必須多一個指針next,至少這樣才看起來有個鏈表的樣子嘛!!
 
 
 
   [cpp]?view plaincopy     
 ?? template<class?K,class?V>?? struct?KVNode?? {?? ????K?_key;?? ????V?_value;?? ????KVNode<K,V>*?_next;?? ?? ????KVNode(const?K&?key,const?V&?value)?? ????????:_key(key)?? ????????,_value(value)?? ????????,_next(NULL)?? ????{}?? };?? 
 
二、哈希表的實現----Inser、Find、Remove
 
 
 
 以數組int a[] = {51, 105, 52, 3, 55, 2, 106, 53, 0}為例
 
 Insert:
 
 老規矩,我們還是得判斷這個key在表中是否存在,如果存在就插入失敗;當兩個key有相同的散列地址時,我們只需將前一個結點的next指針指向新結點即可!那么,我們在同一個散列地上的鏈表進行插入結點時,用頭插好還是尾插好呢?!當然是頭插好了,這樣我們就不用每次遍歷到鏈表的尾結點,這可省了不少事兒!!
 
 以上面這個數組為例,假設51和105分別都已經插入在正確的位置(此時表長53),接下來需要插入52,我們利用頭插進行插入
 
 
 
 
 如果表中的某個位置此時為NULL,當要進行插入時,做法與上述一樣。
 
 
 
   [cpp]?view plaincopy   
   bool?Insert(const?K&?key,const?V&?value)?? ????{?? ?? ????????if?(Find(key))???? ????????????return?false;?? ?????? ????????_CheckSize();?? ????????size_t?index?=?_HashFunc(key,_table.size());?? ????????Node*?tmp?=?new?Node(key,value);?? ????????tmp->_next?=?_table[index];?? ????????_table[index]?=?tmp;?? ????????_size++;?? ????????return?true;?? ????}?? 
 
 
Find: 
 
 
 首先要找到key的散列地址,再在這個地址上掛著的鏈表開始遍歷查找,直到找到相同的key為止。
 
 
 
   [cpp]?view plaincopy   
   Node*?Find(const?K&?key)?? ????{?? ????????if?(_size?==?0)?? ????????????return?NULL;?? ?? ????????size_t?index?=?_HashFunc(key,_table.size());?? ????????Node*?cur?=?_table[index];?? ????????while?(cur)?? ????????{?? ????????????if?(cur->_key?==?key)?? ????????????????return?cur;?? ?? ????????????cur?=?cur->_next;?? ????????}?? ?? ?????????? ????????return?false;?? ????}?? 
 
 
 
 Delete:
 
 刪除一個數據時就是要刪除這個結點,刪除結點的方式與刪除鏈表一個結點的方式是一樣的,只要改變前一個結點的next指針。不過在這之前我們需要通過散列地址找到這個結點。假如要刪除53表示的這個結點
 
 
 
 
 
 
   [cpp]?view plaincopy   
   bool?Remove(const?K&?key)?? ????{?? ????????if(_size?==?0)?? ????????????return?false;?? ?? ????????size_t?index?=?_HashFunc(key,_table.size());?? ????????Node*?cur?=?_table[index];?? ????????Node*?prev?=?NULL;?? ????????while?(cur)?? ????????{?? ????????????while(cur->_key?==?key)?? ????????????{?? ?????????????????? ????????????????if?(prev?==?NULL)?? ????????????????{?? ????????????????????_table[index]?=?cur->_next;?? ????????????????}?? ?????????????????? ????????????????else?? ????????????????{?? ????????????????????prev->_next?=?cur->_next;?? ????????????????}?? ?? ????????????????delete?cur;?? ????????????????_size--;?? ????????????????return?true;?? ????????????}?? ????????????prev?=?cur;?? ????????????cur?=?cur->_next;?? ????????}?? ????????return?false;?? ????}?? 
 
 
具體代碼: 
 
 
 
 
   [cpp]?view plaincopy   
   ?? template<class?K,class?V>?? struct?KVNode?? {?? ????K?_key;?? ????V?_value;?? ????KVNode<K,V>*?_next;?? ?? ????KVNode(const?K&?key,const?V&?value)?? ????????:_key(key)?? ????????,_value(value)?? ????????,_next(NULL)?? ????{}?? };?? ?? template<class?K,class?V>?? class?HashTable?? {?? ????typedef?KVNode<K,V>?Node;?? public:?? ????HashTable()?? ????????:_size(0)?? ????{?? ????????_table.resize(3);?? ????}?? ????~HashTable()?? ????{?? ????????for?(size_t?i=0;?i<_table.size();?++i)?? ????????{?? ????????????Node*?cur?=?_table[i];?? ????????????while?(cur)?? ????????????{?? ????????????????Node*?tmp?=?cur->_next;?? ????????????????delete?cur;?? ????????????????cur?=?tmp;?? ????????????}?? ????????????_size?=?0;?? ????????????_table.clear();?? ????????}?? ????}?? ?? ????Node*?Find(const?K&?key);?? ????bool?Remove(const?K&?key);?? ????bool?Insert(const?K&?key,const?V&?value);?? ????void?Display()?? ????{?? ????????for?(size_t?i=0;?i<_table.size();?++i)?? ????????{?? ????????????printf("Table[%d]->",i);?? ????????????Node*?cur?=?_table[i];?? ????????????while?(cur)?? ????????????{?? ????????????????Node*?next?=?cur->_next;?? ????????????????cout<<cur->_key<<"?";?? ????????????????cur?=?next;?? ????????????}?? ????????????cout<<NULL;?? ????????????cout<<endl;?? ????????}?? ????}?? protected:?? ????void?_CheckSize()?? ????{?? ????????if?(_table.size()?==?0?||?_size?==?_table.size())?? ????????{?? ????????????vector<Node*>?tmpTable;?? ????????????tmpTable.resize(_GetPrimer(_table.size()));?? ?????????????? ????????????for?(size_t?i=0;?i<_table.size();?++i)?? ????????????{?? ????????????????Node*?cur?=?_table[i];?? ????????????????while?(cur)?? ????????????????{?? ????????????????????Node*?next?=?cur->_next;?? ?? ????????????????????size_t?index?=?_HashFunc(cur->_key,tmpTable.size());?? ????????????????????cur->_next?=?tmpTable[index];?? ????????????????????tmpTable[index]?=?cur;?? ?? ????????????????????cur?=?next;?? ????????????????}?? ????????????}?? ????????????_table.swap(tmpTable);?? ????????}?? ????}?? ?? ????size_t?_GetPrimer(size_t?size)?? ????{?? ????????const?int?_PrimeSize?=?28;?? ????????static?const?unsigned?long?_PrimeList[_PrimeSize]?=?? ????????{?? ????????????53ul,?97ul,?193ul,?389ul,?769ul,?? ????????????1543ul,?3079ul,?6151ul,?12289ul,?24593ul,?? ????????????49157ul,?98317ul,?196613ul,?393241ul,?? ????????????786433ul,?? ????????????1572869ul,?3145739ul,?6291469ul,?12582917ul,?? ????????????25165843ul,?? ????????????50331653ul,?100663319ul,?201326611ul,?402653189ul,?? ????????????805306457ul,?? ????????????1610612741ul,?3221225473ul,?4294967291ul?? ????????};?? ????????for?(size_t?i=0;?i<_PrimeSize;?++i)?? ????????{?? ????????????if?(_PrimeList[i]?>?size)?? ????????????{?? ????????????????return?_PrimeList[i];?? ????????????}?? ????????}?? ????}?? ????size_t?_HashFunc(const?K&?key,size_t?size)?? ????{?? ????????return?key%size;?? ????}?? protected:?? ????vector<Node*>?_table;?? ????size_t?_size;????? }; ?
                            總結
                            
                                以上是生活随笔為你收集整理的哈希表---开链法解决哈希冲突的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                            
                                如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。