C語言實現乙個簡易的Hash table 7

2021-09-12 16:40:30 字數 1480 閱讀 3392

上一章我們講了如何根據需要動態設定hash表的大小,在第四章中,我們使用了雙重雜湊來解決hash表的碰撞,其實解決方法有很多,這一章我們來介紹下其他方法。

本章將介紹兩種解決hash表碰撞的方法:

拉鍊法開放位址法

使用拉鍊法,每乙個bucket都會包含乙個鏈結表,當發生碰撞時,就會將該記錄插入在該位置的鏈結表後面,步驟如下:

搜尋時:通過hash函式獲取到key對應的位置,遍歷鏈結表,判斷key是不是搜尋的key,如果是,則返回value,否則返回null刪除時:通過hash函式獲取到key對應的位置,遍歷鏈結表,找到需要刪除的key,如果找到,則將該key對應的記錄從鏈結表中刪除,如果鏈結表中只有一條記錄,則將該位置置為null

拉鍊法的優點是實現起來簡單,但是空間利用率低。每個記錄必須儲存指向鏈結表中下乙個記錄的指標,如果沒有記錄,則指向null,這種方法會浪費一些空間來儲存額外的指標。

開放位址法能解決拉鍊法空間利用率低的問題,發生碰撞時,碰撞的記錄將放置在hash表中的其他bucket中,存放的位置是根據預先確定的規則選擇的,以便在搜尋記錄時可以重複該規則,有如下幾種規則:

線性探測提供了良好的快取效能,但是存在碰撞後遍歷次數多的問題。將發生碰撞key放入下乙個可用的bucket中可能導致後面插入記錄也要往後插,就需要多次迭代。

二次探查法和先行探查類似,不同的是,發生碰撞後,我們會將記錄插入在如下的序列中:i, i + 1, i + 4, i + 9, i + 16, ...i代表通過hash函式獲取到的索引,具體步驟如下:

二次探查法減少發生碰撞後遍歷的次數,並且仍然提供了不錯的快取效能。

雙重hash旨在解決碰撞後遍歷次數多的問題。使用兩次hash函式為插入的記錄選擇新的索引,這個索引會均勻的分布在整個表中,該方法雖然解決了上述問題,但也失去了快取特性,雙重hash是實際專案中常見的衝突管理方法,也是我們在本教程中實現的方法。

C語言實現乙個簡易的掃雷2

ifndef game h define game h define crt secure no warnings 1 include include include include define rows 11 define cols 11 define count 10 void init bo...

C語言實現乙個簡易的Hash table 二

上一章,簡單介紹了hash table,並提出了本教程中要實現的幾個hash table的方法,有search a,k insert a,k,v 和delete a,k 本章將介紹hash table使用的資料結構。hash表中儲存的每一項key value的資料結構 hash table.h ty...

C語言實現乙個簡易的Hash table 三

上一章,我們講了hash表的資料結構,並簡單實現了hash表的初始化與刪除操作,這一章我們會講解hash函式和實現演算法,並手動實現乙個hash函式。本教程中我們實現的hash函式將會實現如下操作 我們將會設計乙個普通的字串hash函式,在偽 中表示如下 function hash string,a...