開放定址是其中一種緩解雜湊衝突的程式設計技術,當使用開放定址作為衝突解決技術時,鍵值對儲存在表(陣列)中,而不是像單獨鍊錶那樣的資料結構中。這意味著我們需要時刻留意雜湊表的尺寸以及當前表中已有的元素數量。因為一旦雜湊表中有太多元素,也將很難找到可用的位置來存放我們新插入的元素,因此這裡我們需要引入乙個重要的術語,負載係數(load factor)
其實就是表中已有元素個數和表尺寸的比例,我們要密切關注這個係數的是因為雜湊表的o(1)恆定時間行為假設負載因子k保持一定的固定值,這意味著一旦k>閾值,我們就需要增加表的大小(理想情況下是指數增長,例如,兩倍)
在上圖中,你會看到有兩種緩解衝突的方法,即單獨鍊錶和線性探測(linear probing),在開放定址(線性探測)技術看來,一旦達到某個閥值,它的時間複雜度就會呈現指數級惡化的趨勢
當我們想要將鍵值對插入雜湊表時,我們對鍵進行雜湊處理並獲得該鍵值對所屬位置的原始位置。如果我們的鍵被雜湊到的位置被占用(此時出現了衝突),對於開放定址來說,同乙個位置中不允許有兩個鍵的,這不是陣列的工作方式,我們要做的是使用乙個探測序列函式(probing seque function) 這裡簡稱p(x),因為我們已從雜湊函式獲取了衝突點的所在位置,現在我們使用p(x)進行探測直到在沿途發現乙個空閒的位置為止
您可以提出無限數量的探測序列,這裡僅提及一些常見的探測函式:
本篇僅介紹線性探測函式進行線性探測,因此給定輸入引數x,當我們進行探測時,我們通常會將變數x初始化為0或1作為乙個起點,如果我們找不到空閒的位置,會依次將x增加1,對以上所有這些探測函式都是一樣的
接下來,這是乙個通用的開放定址插入演算法,假設我們有乙個表的尺寸為n,開放定址演算法首先會初始化變數x=1,因為x是乙個變數,我們要用它來探測,每當我們未能到達閒置的位置時,都需要遞增x,然後我們通過雜湊函式獲得keyhash,而實際上我們首先要檢視表的索引,當表索引被占用意味著它不為空,那麼新索引就是我們雜湊的最初位置(keyhash所指向的起始索引)加上探測函式的總和再於表尺寸n取模運算得到整數,由於我們總是回到表裡,在迴圈中要遞增x。下一次當我們在不同的位置探測時,在while迴圈中,最終我們會找到乙個空閒的位置
x=1keyhash=h(k)index=keyhashwhile table[index]!=null: index=(keyhash+p(k,x)) mod n x=x+1insert(k,v,index)
為了生動說明什麼叫死迴圈地獄,我們這裡看乙個例子,這裡有乙個尺寸為12的雜湊表,並且使用開放定址插入了一些鍵值對,,該雜湊表已經部分填充。 占用的單元格填充有鍵值對(ki,vi)和帶有空令牌φ的空單元格,如下圖所示
假設我們使用探測序列函式p(x)=4x,並且在表中插入乙個新的鍵值對,並且該鍵值對的雜湊值為8,即h(x)=8這意味著我們會在索引8的位置插入該鍵值對,但是該位置已被占用,因為這裡已經有簡直對(k5,v5),所以我們該怎麼辦呢?接下來,我們需要進行探測,所以我們計算: index=h(k)+p(1)=8+4 mod 12=0
此時,如下圖,此時探測函式會跳轉到索引為0的位置,糟糕的是索引1的位置也被占用了,因為(k1,v1)已經存在.
這樣儘管我們具有探測函式,但這種特定的情況下它一直在乙個死迴圈裡面一直做一些毫無意義的事情。
由這個例子我們可知探測函式存在缺陷,他們產生的周期短於表的尺寸,因此,我們要如何處理產生小於表大小的週期的探測功能?一般來說,一致的看法是我們不處理這個問題,相反,我們通過將探測函式的範圍限制在那些產生長度為n的迴圈的函式上來避免這個問題,我們選擇的那些產生的週期正好為n的探測函式,並且這些探測函式確實存在。
線性探測、二次探測和雙重雜湊等技術都受到死迴圈地獄問題的影響,這就是為什麼與這些方法一起使用的探測函式非常特殊的原因。這是乙個很大的話題,將是接下來幾篇文章會重點講述這些,我們目前需要做的是重新定義非常具體的探測函式,這些函式會產生乙個迴圈長度為表尺寸n,並且避免無法插入元素或陷入無限迴圈
注意,開放定址對使用的雜湊函式和探測函式非常敏感。如果使用單獨的鏈結作為衝突解決方法,則不必擔心此問題。
如何解決雜湊衝突
就不自己寫了,直接貼下吧 看了concurrenthashmap的實現,使用的是拉鍊法.雖然我們不希望發生衝突,但實際上發生衝突的可能性仍是存在的。當關鍵字值域遠大於雜湊表的長度,而且事先並不知道關鍵字的具體取值時。衝突就難免會發 生。另外,當關鍵字的實際取值大於雜湊表的長度時,而且表中已裝滿了記錄...
雜湊表如何避免雜湊衝突
開放定址法 核心思想是,如果出現了雜湊衝突,我們就重新探測乙個空閒位置,將其插入。1 線性探測 我們就從當前位置開始,依次往後查詢,看是否有空閒位置,直到找到為止。還記得我們剛講的查詢操作嗎?在查詢的時候,一旦我們通過線性探測方法,找到乙個空閒位置,我們就可以認定雜湊表中不存在這個資料。但是,如果這...
雜湊表,雜湊衝突
什麼是雜湊表?雜湊表 hash table,也叫雜湊表 是根據關鍵碼值 key value 而直接進行訪問的資料結構。也就是說,它通過把關鍵碼值對映到表中乙個位置來訪問記錄,以加快查詢的速度。這個對映函式叫做雜湊函式,存放記錄的陣列叫做雜湊表。關鍵字 雜湊函式 雜湊函式 雜湊位址 優點 一對一的查詢...