雜湊衝突 閉雜湊與開雜湊

2021-09-28 23:51:01 字數 4245 閱讀 4362

閉雜湊:

也叫開放定址法,當發生雜湊衝突時,如果雜湊表未被裝滿,說明在雜湊表中必然還有空位置,那麼可以把key存放到衝突位置中的下乙個空位置中去。

#include using namespace std;

// 雜湊表每個空間給個標記

// empty此位置空, exist此位置已經有元素, delete元素已經刪除

enum state

;// 雜湊函式採用處理餘數法,被模的key必須要為整形才可以處理,此處提供將key轉化為整形的方法

// 整形資料不需要轉化

/*templateclass defhashf

};// key為字串型別,需要將其轉化為整形

class str2int

size_t bkdrhash(const char * str)

return (hash & 0x7fffffff);

}};*/

//線性探測實現

// 為了實現簡單,此雜湊表中我們將比較直接與元素繫結在一起

templateclass hashtable

;public:

hashtable(size_t capacity = 3)

: _ht(capacity)

, _size(0)

bool insert(const pair& val)

// 插入元素

_ht[hashaddr]._state = exist;

_ht[hashaddr]._val = val;

_size++;

return true;

} int find(const k& key)

return hashaddr;

} bool erase(const k& key)

return false;

} size_t size()const

bool empty() const

void swap(hashtable& ht)

private:

size_t hashfunc(const k& key)

/*private:

size_t hashfunc(const k& key)

*/private:

vector_ht;

size_t _size;

};

線性探測優點:實現非常簡單,線性探測缺點:一旦發生雜湊衝突,所有的衝突連在一起,容易產生資料堆積,即:不同關鍵碼佔據了可利用的空位置,使得尋找某關鍵碼的位置需要許多次比較,導致搜尋效率降低

二次探測

線性探測的缺陷是產生衝突的資料堆積在一塊,這與其找下乙個空位置有關係,因為找空位置的方式就 是挨著往後逐個去找,因此二次探測為了避免該問題,找下乙個空位置的方法為:

= ( + )% m,

或者:= ( - )% m

。其中:

i = 1,2,3…

, 是通過雜湊函式

hash(x)

對元素的關鍵碼

key

進行 計算得到的位置,

m是表的大小。 

當表的長度為質數且表裝載因子a不超過0.5時,新的表項一定能夠插入,而且任何乙個位置都不會被探查兩次。因此只要表中有一半的空位置,就不會存在表滿的問題。在搜尋時可以不考慮表裝滿的情況,但在插入時必須確保表的裝載因子a不超過0.5如果超出必須考慮增容。

開雜湊

開雜湊概念開雜湊法又叫鏈位址法(開鏈法),首先對關鍵碼集合用雜湊函式計算雜湊位址,具有相同位址的關鍵碼歸於同一子集合,每乙個子集合稱為乙個桶,各個桶中的元素通過乙個單鏈表鏈結起來,各鍊錶的頭結點儲存在雜湊表中

開雜湊實現

#include using namespace std;

// 雜湊表每個空間給個標記

// empty此位置空, exist此位置已經有元素, delete元素已經刪除

enum state

;// 雜湊桶中元素是用鍊錶串接起來的,因此先給出雜湊桶的結構

templatestruct hashbucketnode

hashbucketnode* _pnext;

v _data;

};template>

class hashbucket

// 雜湊桶中的元素不能重複

pnode* insert(const v& data)

// 3. 插入新元素

pcur = new node(data);

// 採用頭插法插入,效率高

pcur->_pnext = _ht[bucketno];

_ht[bucketno] = pcur;

_size++;

return pcur;

} // 刪除雜湊桶中為data的元素(data不會重複),返回刪除元素的下乙個節點

pnode* erase(const v& data)

位元科技

else

pret = pcur->_pnext;

delete pcur;

_size--;

return pret;

}} return nullptr;

} // 查詢data是否在雜湊桶中

pnode* find(const v& data)

return nullptr;

} size_t size()const

bool empty()const

void clear()

}_size = 0;

} bool bucketcount()const

void swap(hashbucket& ht)

~hashbucket()

private:

size_t hashfunc(const v& data)

private:

vector_ht;

size_t _size; // 雜湊表中有效元素的個數

};

開雜湊增容桶的個數是一定的,隨著元素的不斷插入,每個桶中元素的個數不斷增多,極端情況下,可能會導致一 個桶中鍊錶節點非常多,會影響的雜湊表的效能,因此在一定條件下需要對雜湊表進行增容開雜湊最好的情況是:每個雜湊桶中剛好掛乙個節點,再繼續插入元素時,每一次都會發生雜湊衝突,因此,在元素個數剛好等於桶的個數時,可以給雜湊表增容。

/*void _checkcapacity()

// 將節點插入到新雜湊表中

if (nullptr == ppos)

else

// 獲取原雜湊表bucketidx桶中下乙個節點

pcur = _ht[bucketidx];}}

newht._size = _size;

this->swap(newht);

} }*/

雜湊之開雜湊,閉雜湊

有沒有一種方法時間複雜度,僅僅o 1 尼,那麼我們就要構造一種儲存結構,通過某種函式是之元素與它對應的關鍵碼之間能建立一一對映的關係,那麼自然通過之中一一對映的關係,我們就可以很快的找到我們需要的元素。所以進入雜湊這個這題首先我們需要乙個我們下標,這個下表在雜湊當中 我們就稱之為雜湊位址。而這個位址...

雜湊衝突 開雜湊的實現

開雜湊解決雜湊衝突的方法是通過key值計算出在雜湊表中的儲存位置,計算方法同之前的閉雜湊一樣,key capacity的值為在雜湊表中的儲存位置。若兩個鍵值對計算出來的位置相同,就把這兩個鍵值對通過單鏈表鏈結 頭插的形式 起來儲存在這個位置上,這稱為雜湊桶。鍊錶的頭結點儲存在雜湊表中。開雜湊的實現 ...

D OJ練習 雜湊查詢實驗(閉雜湊 開雜湊)

請設計乙個整型閉雜湊表,雜湊函式為除留餘數法,處理衝突時的探查方法為線性探查法,其中雜湊表的長度 除留餘數法的模和關鍵碼的個數由鍵盤輸入,再根據輸入由鍵盤輸入所有的關鍵碼。分別對三個待查值在雜湊表中進行查詢,如果找到了輸出位置,如果沒找到,輸出 none 並把該待查值插入到雜湊表中,如果雜湊表滿輸出...