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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

哈希表线性探测

發布時間:2025/3/19 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 哈希表线性探测 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ??HashTable-散列表/哈希表,是根據關鍵字(key)而直接訪問在內存存儲位置的數據結構。

? ?它通過一個關鍵值的函數將所需的數據映射到表中的位置來訪問數據,這個映射函數叫做散列函數,存放記錄的數組叫做散列表。

  • 哈希沖突/哈希碰撞

? ? 不同的Key值經過哈希函數Hash(Key)處理以后可能產生相同的值哈希地址,我們稱這種情況為哈希沖突。任意的散列函數都不能避免產生沖突。

? ?我給大家介紹的是哈希表的線性探測,線性探測的基本思路:

? ? ? ?1.用一個數據除以散列表的長度,余數是多少,就把這個數放在散列表下標相同的地方。

? ? ? ?2.如果發生哈希沖突,就看下一個位置是否有數據,一直到沒有哈希沖突,就把這個數據放在此位置。

? ? ? ?3.如果已經試探到最后一個位置,但前面還有位置沒有試探,那么我們就從開始位置繼續試探,直到全部位置試探成功。

實現代碼:

Hash.h中

//哈希表中存放數據的狀態 enum?State {EMPTY,//沒有數據DELETE,//刪除數據后EXIST//有數據 }; template?<class?K> class?HashTable { public://構造函數HashTable():_table(NULL),?state(NULL),?_size(0),?_capatity(0){}//構造函數HashTable(size_t?size):_table(new?K[size]),?_state(new?State[size]),?_capatity(size),?_size(0){for?(int?i?=?0;?i?<?_capatity;?i++){_state[i]?=?EMPTY;}}//插入數據bool?Insert(const?K&?key){//檢測靜態哈希表是否已滿if?(_size?==?_capatity){cout?<<?"哈希表已滿!"?<<?endl;return?false;}int?index?=?_HashFunc(key);while?(_state[index]?==?EXIST){index++;//哈希沖突,找下一個位置//最后一個位置有數據,從頭開始找位置if?(index?==?_capatity){index?=?0;}}//哈希不沖突,直接放數據_table[index]?=?key;_state[index]?=?EXIST;_size++;return?true;}//查找int?Find(const?K&?key){int?index?=?_HashFunc(key);while?(_state[index]?!=?EMPTY){//找到元素if?(_table[index]?==?key&&_state[index]?==?EXIST){return?index;}//如果算出的位置,不是要找的元素,index++;index++;//最后一個位置不是,就從頭開始找if?(index?==?_capatity){index?=?0;}}return?-1;}void?print(){for?(int?i?=?0;?i?<?_capatity;?i++){if?(_state[i]?==?EXIST){printf("[%d]EXIST:%d\n",i,?_table[i]);}else?if?(_state[i]?==?DELETE){printf("[%d]DELETE:NULL\n",?i,?_table[i]);}else{printf("[%d]EMPTY:NULL\n",?i);}}}//刪除某一位置元素bool?Remove(const?K&?key){int?index?=?Find(key);//找到這個元素//刪除這個元素if?(index?!=?-1){_state[index]?=?DELETE;_size--;return?true;}return?false;} protected://算出數據在哈希表中的位置(哈希不沖突)int?_HashFunc(const?K&?key){return?key%_capatity;} protected:K*?_table;//數組State*?_state;//狀態數組size_t?_size;//數組大小size_t?_capatity;//數組的容量 };

test.cpp中

#include?<iostream> using?namespace?std; #include?"Hash.h" void?Test() {HashTable<int>?ht(10);ht.Insert(24);ht.Insert(20);ht.Insert(36);ht.Insert(23);ht.Insert(30);ht.print();int?ret?=?ht.Find(30);cout?<<?"下標為:"<<ret?<<?endl;ht.Remove(30);ht.print();} int?main() {Test();system("pause");return?0; }

上面的代碼有不完善的地方,我們在處理哈希問題是,有這樣的問題存在。散列表載荷因子的問題。

? ? 載荷因子=填入表中的元/散列表的長度

? ?載荷因子與“填在表中元素的個數”成正比,載荷因子越大,填入表中的元素越多,產生沖突的可能性越大。反之,則相反。

? ? 載荷因子應該限制在0.7—0.8以下,超過0.8,查找CPU緩存不命中,效率就比較低,所以一般載荷因子為0.8就應該擴容。

? ?所以上面的檢查容量應該稍微改一下

代碼:

bool?Insert(const?K&?key){//檢測靜態哈希表是否已滿/*if?(_size?==?_capatity){cout?<<?"哈希表已滿!"?<<?endl;return?false;}*///考慮到載荷因子在0.7~0.8一下比較好,這樣檢查容量比較好if?(10?*?_size?>=?8?*?_capatity){_CheckCapatity();}int?index?=?_HashFunc(key);while?(_state[index]?==?EXIST){index++;//哈希沖突,找下一個位置//最后一個位置有數據,從頭開始找位置if?(index?==?_capatity){index?=?0;}}//哈希不沖突,直接放數據_table[index]?=?key;_state[index]?=?EXIST;_size++;return?true;}//交換void?_Swap(HashTable<K>?tmp){swap(_size,?tmp._size);swap(_capatity,?tmp._capatity);swap(_state,?tmp._state);swap(_table,?tmp._table);}//檢查容量void?_CheckCapatity(){HashTable<K>?tmp(2?*?_capatity);for?(int?i?=?0;?i?<?_capatity;?i++){tmp.Insert(_table[i]);}_Swap(tmp);}

上面只能存儲數據,如果是字符串,怎么辦哪?所以我們想處理字符串,可以寫一個自定義類型,然后利用特化來處理字符串。

代碼如下:

#include?<string> //哈希表中存放數據的狀態 enum?State {EMPTY,//沒有數據DELETE,//刪除數據后EXIST//有數據 }; template?<class?K> //處理 struct?DefaultFunc {size_t?operator()(const?K&?key){return?key;} }; //自定義類型 template<> struct?DefaultFunc<string>//特化 {size_t?value?=?0;size_t?operator()(const?string&?str){for?(int?i?=?0;?i?<?str.size();?i++){value?+=?str[i];}return?value;} }; template?<class?K,?template?<class>class?HashFunc?=?DefaultFunc> class?HashTable { public://構造函數HashTable():_table(NULL),?state(NULL),?_size(0),?_capatity(0){}//構造函數HashTable(size_t?size):_table(new?K[size]),?_state(new?State[size]),?_capatity(size),?_size(0){for?(int?i?=?0;?i?<?_capatity;?i++){_state[i]?=?EMPTY;}}//插入數據bool?Insert(const?K&?key){//檢測靜態哈希表是否已滿/*if?(_size?==?_capatity){cout?<<?"哈希表已滿!"?<<?endl;return?false;}*///考慮到載荷因子在0.7~0.8一下比較好,這樣檢查容量比較好if?(10?*?_size?>=?8?*?_capatity){_CheckCapatity();}int?index?=?_HashFunc(key);while?(_state[index]?==?EXIST){index++;//哈希沖突,找下一個位置//最后一個位置有數據,從頭開始找位置if?(index?==?_capatity){index?=?0;}}//哈希不沖突,直接放數據_table[index]?=?key;_state[index]?=?EXIST;_size++;return?true;}//查找int?Find(const?K&?key){int?index?=?_HashFunc(key);while?(_state[index]?!=?EMPTY){//找到元素if?(_table[index]?==?key&&_state[index]?==?EXIST){return?index;}//如果算出的位置,不是要找的元素,index++;index++;//最后一個位置不是,就從頭開始找if?(index?==?_capatity){index?=?0;}}return?-1;}void?print(){/*for?(int?i?=?0;?i?<?_capatity;?i++){if?(_state[i]?==?EXIST){printf("[%d]EXIST:%d\n",i,?_table[i]);}else?if?(_state[i]?==?DELETE){printf("[%d]DELETE:NULL\n",?i,?_table[i]);}else{printf("[%d]EMPTY:NULL\n",?i);}}*/for?(int?i?=?0;?i?<?_capatity;?i++){if?(_state[i]?==?EXIST){cout?<<?i?<<"-"<<?"EXIST:"?<<?_table[i]?<<?endl;}else?if?(_state[i]?==?DELETE){cout?<<?i?<<"-"<<?"DELETE:"?<<?"NULL"?<<?endl;}else{cout?<<?i?<<"-"<<?"EMPTY:"?<<?"NULL"?<<?endl;}}}//刪除某一位置元素bool?Remove(const?K&?key){int?index?=?Find(key);//找到這個元素//刪除這個元素if?(index?!=?-1){_state[index]?=?DELETE;_size--;return?true;}return?false;} protected://算出數據在哈希表中的位置(哈希不沖突)/*int?_HashFunc(const?K&?key){return?key%_capatity;}*/int?_HashFunc(const?K&?key){HashFunc<K>?ht;return?ht(key)?%?_capatity;}//交換void?_Swap(HashTable<K>?tmp){swap(_size,?tmp._size);swap(_capatity,?tmp._capatity);swap(_state,?tmp._state);swap(_table,?tmp._table);}//檢查容量void?_CheckCapatity(){HashTable<K>?tmp(2?*?_capatity);for?(int?i?=?0;?i?<?_capatity;?i++){tmp.Insert(_table[i]);}_Swap(tmp);} protected:K*?_table;//數組State*?_state;//狀態數組size_t?_size;//數組大小size_t?_capatity;//數組的容量 };

test.cpp中

#include?<iostream> using?namespace?std; #include?"Hash.h" //void?Test() //{ // HashTable<int>?ht(10); // ht.Insert(24); // ht.Insert(20); // ht.Insert(36); // ht.Insert(23); // ht.Insert(30); // ht.print(); // // int?ret?=?ht.Find(30); // cout?<<?"下標為:"<<ret?<<?endl; // // ht.Remove(30); // ht.print(); // //}void?Test1() {HashTable<string>?ht(10);ht.Insert("杭哥");ht.Insert("張哥");ht.Insert("詹姐");ht.Insert("亮哥");ht.Insert("蛋蛋");ht.print();int?ret?=?ht.Find("蛋蛋");cout?<<?"下標為:"?<<?ret?<<?endl;ht.Remove("亮哥");ht.print(); } int?main() {//Test();Test1();system("pause");return?0; }


轉載于:https://blog.51cto.com/mnt3918290/1771958

總結

以上是生活随笔為你收集整理的哈希表线性探测的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 国产亚洲视频在线观看 | 国产精品第三页 | 四虎网站最新网址 | 久久久久久久久久99 | 欧美黑人添添高潮a片www | 人妻换人妻a片爽麻豆 | 国产内射一区二区 | 在线观看亚洲区 | 男操女视频网站 | 老妇高潮潮喷到猛进猛出 | 特黄三级| 亚洲日本免费 | 麻豆短视频 | 欧美成人综合 | 黑帮大佬和我的三百六十五天 | 精品无码一区二区三区在线 | 国产av无码专区亚洲a∨毛片 | 亚洲毛茸茸 | 久久久久青草 | 性生生活大片又黄又 | 久久国产精品系列 | 成人自拍视频 | 亚洲天堂资源网 | 能直接看的av网站 | 天堂一二三区 | 操极品女神 | 性感美女一区二区三区 | 欧美熟妇精品黑人巨大一二三区 | 国产精品久久久久野外 | 农村搞破鞋视频大全 | 91精品国产91久久久久福利 | 欧美成人免费在线视频 | 成人毛片视频网站 | 特级西西444www大胆免费看 | 黄色网页大全 | 中文字幕第一页在线播放 | 中文字幕一区av | 日韩欧美视频在线 | av免费一区| 成人动漫在线观看 | 免费中文字幕av | 99色在线观看| 成人午夜sm精品久久久久久久 | 在线国产视频一区 | 青青草97国产精品免费观看 | 91新网站 | 毛片在哪看 | 林雅儿欧洲留学恋爱日记在线 | 日韩欧美精品一区二区 | 国产真实乱人偷精品视频 | 国产精品视频一二三区 | 久久久夜夜夜 | 欧美日韩高清一区二区 国产亚洲免费看 | 中文字幕 自拍偷拍 | 浮妇高潮喷白浆视频 | 亚洲经典一区二区三区 | 亚欧洲精品视频 | 粉嫩aⅴ一区二区三区四区五区 | 亚洲三级黄色片 | 在线国产一区二区 | 日本福利网站 | 韩国一级一片高清免费观看 | 影音先锋国产资源 | 国产精品久久久久久久免费 | 日韩av片在线播放 | 久久精品欧美一区二区三区不卡 | 色偷偷av一区二区三区 | 国产a免费观看 | 视色网| 日韩毛片一区 | 国产精品欧美一区二区三区 | 亚洲av永久一区二区三区蜜桃 | 中文字幕第22页 | 婷婷在线看| 一级黄色片免费看 | 中文一区二区在线播放 | 捆绑调教在线观看 | 成年人午夜影院 | 国产亚韩| 色呦 | 久久艹免费视频 | 国产精品色在线 | 亚洲精品乱码久久久久久日本蜜臀 | av在线在线 | 国产精品美女一区二区三区 | 欧美日韩免费观看一区=区三区 | 粉嫩av一区二区三区免费观看 | 日韩av一| 成人免费看片视频 | 黄色网在线| 天天射,天天干 | 波多野结衣在线一区二区 | 72pao成人国产永久免费视频 | 蜜臀精品一区二区三区 | 九九色网站 | 国产精品va无码一区二区三区 | 午夜视频福利在线观看 | 波多野结衣在线 | 亚洲精品美女在线观看 |