之前一篇博文中提過如何用開鏈法實現雜湊表
這裡是鏈結
那麼對於雜湊表的實現,還有另外一種方法的實現,這就是雜湊開放定址法來實現。該方法也是用來處理雜湊衝突的。解決思想如下:
現有關鍵字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 即有衝突時,怎麼辦呢?我們可以從生活中找尋思路。試想一下,當...