日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

哈希表---开链法解决哈希冲突

發布時間:2023/12/31 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 哈希表---开链法解决哈希冲突 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

上篇文章已經寫過構造哈希表時用開放定址法解決哈希沖突,這次我就來寫寫這個開鏈法解決哈希沖突的問題!

一、結點定義

我們已經知道開鏈法大概是一種什么結構了,(如果不知道,這里有講哦點我點我)顯而易見,實現哈希桶的話我們就必須多一個指針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()));??
  • ????????????//將原表_table中的結點直接放入新表中??
  • ????????????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;???//已有的數據個數??
  • }; ?
  • 總結

    以上是生活随笔為你收集整理的哈希表---开链法解决哈希冲突的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。