雜湊表簡易入門

來源:互聯網
上載者:User

標籤:style   blog   color   使用   io   資料   for   ar   

什麼是雜湊表

雜湊表(Hash table,也叫散列表),是根據關鍵碼值(Key value)而直接進行訪問的資料結構。也就是說,它通過把關鍵碼值對應到表中一個位置來訪問記錄,以加快尋找的速度。這個映射函數叫做雜湊函數,存放記錄的數組叫做雜湊表。雜湊表作為一種高效的資料結構,有著廣泛的應用。如果雜湊函數設計合理,理想情況下每次查詢的時間花費僅僅為 O(h/r),即和雜湊表容量與剩餘容量的比值成正比。只要雜湊表容量達到實際使用量的大約 1.5 倍以上,查詢花費的時間基本就可以認為恒為 O(1)。

一個通俗的例子是,為了尋找電話簿中某人的號碼,可以建立一個按照人名首字母順序排列的表(即建立人名x到首字母F(x)的一個函數關係),在首字母為W的表中尋找“王”姓的電話號碼,顯然比直接尋找就要快得多。這裡使用人名作為關鍵字,“取首字母”F()是這個例子中的雜湊函數,存放首字母的表對應雜湊表。關鍵字和雜湊函數可以任意選擇。在競賽中的雜湊函數一般是直接把關鍵字對一個素數模數(簡單粗暴)。

 

與平衡二叉樹的類比

Map是STL的一個關聯容器,它提供一對一的資料處理能力(其中第一個可以稱為關鍵字,每個關鍵字只能在map中出現一次,第二個可能稱為該關鍵字的值)。它的內部實現是一個紅/黑樹狀結構(紅/黑樹狀結構是平衡二叉樹的一種),平衡二叉樹中的部所有的資料都是有序的,並且可以通過O(logn)的複雜度尋找、插入或刪除一個關鍵字。而在理想情況下,雜湊表可以用O(1)的複雜度尋找、插入一個關鍵字。

 

處理碰撞

對不同的關鍵字可能得到同一散列地址,即k_1 != k_2,而f(k_1)=f(k_2),這種現象稱碰撞(Collision)。具有相同函數值的關鍵字對該散列函數來說稱做同義字。

處理碰撞的方法有很多,在競賽中一般採用單獨鏈表法:將雜湊到同一個儲存位置的所有元素儲存在一個鏈表中。在實現中一般用一個數組來代替鏈表。

 

演算法實現

我們通過山寨一個STL Map來加深對雜湊表的理解。

map常用操作有兩種:

  1. 查詢map中是否含有給定關鍵字Key;
  2. 將(Key,Value)插入到map中。如果map中已經存在Key,那麼就用新的Value覆蓋舊的值。

 

 1 typedef long long LL; 2 typedef LL KT;// Key的類型 3 typedef LL VT;// Value的類型 4 class Hash_Map { 5 private: 6     static const int SEED = 29989;// 一個比實際容量稍大的素數 7     static const int MAXN = 30000;// 雜湊表最大的元素個數 8     struct ELEM {// 定義鏈表的資料類型 9         KT key;// 元素的關鍵字10         VT value;// 元素的值11         int next;// 指向鏈表的下一個位置12     }elems[MAXN];// 鏈表所使用的數組13     int head[SEED], cur;// 表頭與元素個數14     int hash(KT key){// 雜湊函數15         return key % SEED;16     }17 public:18     Hash_Map() {// 建構函式19         clear();20     }21     void clear() {// 初始化雜湊表22         cur = 0;23         memset(head,-1,sizeof(head));24     }25     void insert(KT key, VT value) {// 插入一個關鍵字26         int h = hash(key);// 用雜湊Function Compute關鍵字在雜湊表中的地址27         for (int i=head[h]; i!=-1; i=elems[i].next) {// 遍曆雜湊值為h的鏈表中的所有元素28             if (key==elems[i].key) {// 如果key已經存在29                 elems[i].value = value;// 覆蓋舊的value30                 return;31             }32         }33         // key不存在,則將其插入鏈表34         elems[cur].value = value;35         elems[cur].key = key;36         elems[cur].next = head[h];37         head[h] = cur++;38     }39     VT find(KT key) {40         int h = hash(key);41         for (int i=head[h]; i!=-1; i=elems[i].next) {42             if (key==elems[i].key) {43                 return elems[i].value;44             }45         }46         return -1;47     }48 }hs;

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.