哈希表概念
?
問題:
在內存中用數(shù)組存儲50000個單詞,用數(shù)組下標去找單詞很快,但我們在單詞軟件中不知道單詞在數(shù)組中的下標.
如a的下標為0,z最后單詞的下標為49999,如果以這種方式來找的話,那么查找z開頭的單詞速度就會相當?shù)穆?/p>
方案:
想一個方法快速的找到單詞相對應的下標,哈希函數(shù)的定義
將數(shù)據(jù)元素的關鍵字K作為自變量,通過一定的函數(shù)關系(稱為哈希函數(shù)),計算出的值,即為該元素的存儲地址
即其本身還是一個數(shù)組,只不過通過一個算法快速的找到其下標地址而已.
哈希函數(shù)的沖突
當用哈希函數(shù)新增元素時,算出來該元素的存儲地址若已經存有元素的話,那么就稱之為沖突,那么就得想辦法來避免這種沖突.
示例
下面來看一個實際的例子.只做演示
以一個元素為20個的數(shù)組為例子
1.哈希函數(shù)
取數(shù)組大小的余數(shù),即5%20和25%20是相同的.
2.插入25,余數(shù)為5
所以其存儲地址為5
3.插入5
由于插入5時,與25的存儲地址發(fā)生了沖突,就需要處理,這里使用了開發(fā)地址法的線性探測方法
線性探測
即若遇到地址發(fā)生了沖突,則沿著數(shù)組的下標繼續(xù)尋找空白單元
查找
如查找25,算出來的存儲地址為5,馬上就能找到,即實現(xiàn)了1次查找,刪除操作與查找相同,找到以后賦空值就可
實現(xiàn)
public class IntHashTable {private int[] items;public IntHashTable(int size){items = new int[size];for (int i = 0; i < items.Length; i++){items[i] = -1;}}private int hashFunc(int key){return key % items.Length;}public void Insert(int item){int hashVal = hashFunc(item);while (items[hashVal]!=-1){hashVal++;}items[hashVal] = item;}public int Find(int key){int hashVal = hashFunc(key);while (items[hashVal]!=-1){if (items[hashVal] == key)return hashVal;hashVal++;hashVal = hashFunc(hashVal);}return -1;}public void Delete(int key){int hashVal = hashFunc(key);while (items[hashVal] != -1){if (items[hashVal] == key){items[hashVal] = -1;}hashVal++;hashVal = hashFunc(hashVal);}}public static void Main(){IntHashTable ht = new IntHashTable(20);ht.Insert(11);ht.Insert(12);ht.Insert(32);ht.Find(32);ht.Delete(32);} }鏈地址法
將發(fā)生沖突的存在一個鏈表里面,并且保持鏈表有序.如下
public class Link {public int Value { get; set; }public Link Next { get; set; } }class SortedList {private Link first;public SortedList(){ first = null;}public void Insert(Link theLink){int key = theLink.Value;Link previous = null;Link current = first;while (current != null && key > current.Value){previous = current;current = current.Next;}if (previous == null)first = theLink;elseprevious.Next = theLink;theLink.Next = current;}public void Delete(int key){Link previous = null;Link current = first;while (current != null && key != current.Value){previous = current;current = current.Next;}if (previous == null)first = first.Next;elseprevious.Next = current.Next;}public Link Find(int key){Link current = first;while (current != null && current.Value <= key){if (current.Value == key)return current;current = current.Next;}return null;} }public class LinkHashTable {private SortedList[] items;public LinkHashTable(int size){items = new SortedList[size];for (int i = 0; i < items.Length; i++){items[i] = new SortedList();}}private int hashFunc(int key){return key % items.Length;}public void Insert(int item){int hashVal = hashFunc(item);var link = items[hashVal];link.Insert(new Link() { Value = item });}public int Find(int key){int hashVal = hashFunc(key);var link = items[hashVal];return link.Find(key).Value;return -1;}public void Delete(int key){int hashVal = hashFunc(key);var link = items[hashVal];link.Delete(key);} }二次探測
當發(fā)生沖突時才進行探測,猶如人左右張望,先看右邊有無空位,再看左邊有無空位,即先確認左右,
如上圖的最后一個關鍵字3,
3和47沖突,先找到4(97)又發(fā)生沖突則找左邊2空位.
遵照哈希函數(shù)公式即可
轉載于:https://www.cnblogs.com/Clingingboy/archive/2011/01/20/1940700.html
《新程序員》:云原生和全面數(shù)字化實踐50位技術專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結
- 上一篇: 天啊!我的xbox360突然不读盘了。。
- 下一篇: 有关热点图