場景:在我們編寫基本的c語言**的時候,比如我們需要輸入乙個變數,然後對變數進行操作,最後返回乙個結果,那麼在我們對變數進行操作的時候,我們的編譯器就會對你的變數進行檢查,他會看你的變數是否定義、定義格式是否正確等。這裡就會存在查詢問題,如果我們採用二叉查詢樹等查詢樹來進行查詢的話會發現由於需要使樹保持平衡,我們會多花很多額外的功夫,導致查詢效率低下,此時,雜湊表就應運而生。所以我們說雜湊表可以用來進行查詢或者說他是一種查詢的手段(當然雜湊表的功能不止於此)。
基本思想:直接「算出」要查詢物件的位置。如果讀者學習過python的話,這裡的雜湊表很像python中的字典。
雜湊查詢的基本工作:
①計算位置:通過構造雜湊函式來確定關鍵字的儲存位置。
②解決衝突:應用某種策略解決多個關鍵字位置相同的問題
。注意:我們在設計雜湊函式的時候應該本著盡可能通過該函式可以直接找到關鍵字的儲存位置,但是在實際情況中,我們很難做到乙個函式可以使用於所有的關鍵字,那麼如果兩個關鍵字的儲存位置一樣的話,我們稱之為衝突,發生了衝突,我們就要解決衝突,這就是雜湊查詢的基本工作。
雜湊函式的構造方法:乙個好的雜湊函式應該考慮這兩個因素:計算簡單(以便提高轉換速度)和關鍵字對應的位址空間盡可能的分布均勻常見思路:換個位置:開放位址法:當發生衝突的時候,我們重新按照某種規則去尋找空位來儲存關鍵字。同一位置的衝突物件放在一起:鏈位址法,我們將同一位置發生衝突的物件用鍊錶放在一起,最後再查詢的時候我們就從鍊錶的表頭開始查詢就ok。
開放位址法:若發生了第i次衝突,試探的下乙個位址將增加di,基本公式見下圖
裝填因子α:關鍵字序列長度除以雜湊表表長。
對於開放位址法:我們的解決方案有:線性探測、平方探測、雙雜湊。
線性探測:我們將下面的關鍵字序列放入到如圖所示的雜湊位址中,按照我們尋找最小素數的原則來確定表長,雜湊函式可以設定成關鍵字模11。然後我們採用線性探測法來進行關鍵字的排放,即如果當前的關鍵字的儲存位置存在衝突,我們就探測其後的儲存位址是否有衝突,如果沒有,我們就將關鍵字放在這裡,如果存在衝突,我們就繼續向後探測,由於是線性探測,因此我們每次只向後推進乙個單位長度。缺點:當我們算出來的位址存在衝突時,我們會向後探測,如果這個位置還有元素要向這裡放的話那麼我們會繼續向後探測(假設探測兩個單位長度後有空位),我們可以想到,如果這種情況頻繁發生的話,那麼在這個位置處就會發生聚集現象,即大量的資料被放在第一次衝突的位置之後的連續的很多位置上。
對於上圖,我們將序列中的每個關鍵字進行模11運算,得到的結果放到對應的位址中,如果有衝突的,我們就向後查詢,直到找到空位,我們就將該元素放入到該空位i中。如此迴圈,直至所有關鍵字均被放入到儲存位址中。
平方探測:增量序列為加減 i 的平方
平方探測的方法跟線性探測類似,但是不是挨個查詢,而是先查詢 1 的平方,如果沒有空位的話就查詢 -1 的平方,如果還是沒有空位的話就查詢 +2 的平方…直到找到空位。那麼我們可以發現,平方探測不像線性探測那樣挨個查詢,平方探測是跳躍式的進行查詢,因此我們會有這樣的疑問,會不會雜湊表中存在空位,但是我們缺不能探測出來呢?答案是肯定的,但是我們有如下結論:如果雜湊表長度是某個4k + 3(k為正整數)形式的素數時,平方探測發就可以探測到整個雜湊空間。
鏈位址法:我們將模值(11)放在節點的資料域,指標域指向乙個陣列,但是這個陣列不進行儲存,只表示位址指向乙個單鏈表,我們將有衝突的元素都放在單鏈表中。在查詢的時候,我們先通過雜湊函式算出陣列的下標,然後在這個下標下去遍歷單鏈表,直到找到該數值。
雜湊表(雜湊表)原理詳解
雜湊表 hash table,也叫雜湊表 是 根據關鍵碼值 key value 而直接進行訪問的資料結構。也就是說,它通過把關鍵碼值對映到表中乙個位置來訪問記錄,以加快查詢的速度。這個對映函式叫做 雜湊函式 存放記錄的陣列叫做 雜湊表。或者 把任意長度的輸入 又叫做預對映,pre image 通過雜...
雜湊表(雜湊表)原理詳解
t什麼是雜湊表?雜湊表 hash table,也叫雜湊表 是根據關鍵碼值 key value 而直接進行訪問的資料結構。也就是說,它通過把關鍵碼值對映到表中乙個位置來訪問記錄,以加快查詢的速度。這個對映函式叫做雜湊函式,存放記錄的陣列叫做雜湊表。記錄的儲存位置 f 關鍵字 這裡的對應關係f稱為雜湊函...
雜湊表 雜湊表 的實現原理
雜湊表可以表述為,是一種可以根據關鍵字快速查詢資料的資料結構。通常情況下,不論雜湊表中資料有多少,增加,刪除,改寫資料的複雜度平均都是o 1 效率非常高。如果說每乙個資料它都對應著乙個固定的位置,那我們查詢特定乙個資料時,就可以直接檢視這個資料對應的位置是否存在資料。乙個形象的例子就是學生在教室中的...