雜湊(閉雜湊)開放定址法實現

2021-08-19 18:21:20 字數 3164 閱讀 4168

之前一篇博文中提過如何用開鏈法實現雜湊表

這裡是鏈結

那麼對於雜湊表的實現,還有另外一種方法的實現,這就是雜湊開放定址法來實現。該方法也是用來處理雜湊衝突的。解決思想如下:

現有關鍵字17,60,29,38

如何確定位址??可以看見該錶的長度為11,那麼使用關鍵字取餘該錶的長度,得到的餘數就是該關鍵字的位址,17則餘6,60則餘5,29則餘7,那麼38也餘了5,但是5這個位址已經存在關鍵字了,所以採用一種線性探測的方法,向後尋找乙個位置,可以看見6這個位址也已經有了關鍵字,那就繼續向後尋找,直到找到第乙個空的位置,存放即可。

線性探測的方法在某種程度上衝突的機率會加大,比如說當有數十個餘數相同的關鍵字時,雜湊表的衝突就會尤為的集中,那麼還有二次探測的方法,如果當前的位置衝突,向後移動2的衝突次方,即如果第一次衝突就移動1的2次方,第二次再衝突,移動-1的2次方,在該例子中,38就被放到了4這個位子,因為第一次移動是衝突的,則第二次是移動-1次了,即向左移動乙個

對於第二種方式對於衝突能夠比較分散。

///線性探測//

namespace open

}; struct _hashfuncstring

return (hash & 0x7fffffff);

} size_t operator()(const string& key)

};enum state

; templatestruct hashnode

};templateclass hashtable

bool insert(const k& key, const v& value)

size_t index =hashfunc(key);

while (_tables[index]._state == exist)

}_tables[index]._key = key;

_tables[index]._value = value;

_tables[index]._state = exist;

_size++;

return true;

} size_t hashfunc(const k& key)

//表不能滿,滿了之後會死迴圈

node* find(const k& key)

else

}++index;

if (_tables.size() == index)

index = 0;

}return null;

} void checkcapacity()

hashtablenewht;

newht._tables.resize(newsize);

for (size_t i = 0; i < _tables.size(); ++i)

}_tables.swap(newht._tables);

}} bool remove(const k& key)

else

}private:

vector_tables;

size_t _size;//為什麼要加這個size,hash表不是線性的,是對映進去的,這個size代表資料的多少

}; void test()

; hashtableht;

for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); ++i)}}

/二次線性探測///

namespace open;

templatestruct hashnode

};//除string外的型別

templatestruct _hashfunc

};struct _hashfuncstring

return (hash & 0x7fffffff);

} size_t operator()(const string& key)

};template>//針對string需要給乙個其他的模板

class hashtable

bool insert(const k& key, const v& value)

size_t i = 1;

size_t index = hashfunc(key);

while (_tables[index]._state == exist)

}_tables[index]._key = key;

_tables[index]._value = value;

_tables[index]._state = exist;

_size++;

return true;

} //string不支援

size_t hashfunc(const k& key)

//表不能滿,滿了之後會死迴圈

node* find(const k& key)

else

}++index;

if (_tables.size() == index)

index = 0;

}return null;

} void checkcapacity()

hashtablenewht;

newht._tables.resize(newsize);

for (size_t i = 0; i < _tables.size(); ++i)

}_tables.swap(newht._tables);

}} bool remove(const k& key)

else

}private:

vector_tables;

size_t _size;//為什麼要加這個size,hash表不是線性的,是對映進去的,這個size代表資料的多少

}; /*void test()

; hashtableht;

for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); ++i)

}*//*void test()

*/}

雜湊 開放定址法

引起雜湊衝突的乙個原因可能是 雜湊函式設計不夠合理。雜湊函式設計原則 雜湊函式的定義域必須包括需要儲存的全部關鍵碼,而如果雜湊表允許有m個位址時,其值域必須在0到m 1之間 雜湊函式計算出來的位址能均勻分布在整個空間中 雜湊函式應該比較簡單 閉雜湊typedef int keytype typede...

開放定址法實現雜湊表

使用分離鏈結法實現雜湊表時需要額外的空間來儲存指標,而且需要給新單元動態分配空間,導致演算法的速度減慢。開放定址法一次分配表的大小,可以使用線性雜湊,平方雜湊,雙重雜湊等等方法,這些方法除了雜湊函式不相同之外,對於雜湊表的大小要求也不一樣。平方雜湊需要使表的大小是儲存元素的兩倍以上,這樣總能找到空槽...

雜湊衝突處理 開放定址法

設計得再好的雜湊函式也不可能完全避免衝突,這就像我們再健康也只能盡量預防疾病,但卻無法保證永遠不得病一樣,既然衝突不能避免,就要考慮如何處理它。那麼當我們在使用雜湊函式後發現兩個關鍵字key1 key2,但是卻有f key1 f key2 即有衝突時,怎麼辦呢?我們可以從生活中找尋思路。試想一下,當...