目錄
雜湊表,就是下標可以為字母的陣列。
假設現有乙個陣列int a[100],想查詢其中第40個元素,則直接輸入a[40]就可以了,時間複雜度為o ( 1 ) o(1)o(1)。
問題在於,當下標不是數字,而是乙個字串的時候,可能需要乙個超大的空間才能將所有下標妥善地存放在特定的位置。例如,若以大小寫字母作為下標索引,那麼一位就需要預留52個空間,10位就需要52的10次方 這麼大的空間,根本沒有裝置可以滿足。
好在,52的10次方這麼龐大的數字也超出了正常人的使用範圍,無論多長的索引,我們能用上的值也絕對是有限的。
例如,現有下面三個字串作為下標
key1 = "microcold";
key2 = "tinycold";
key3 = "microcool";
其實只需要選取頭、尾兩個字母,就能很好地區分這三個字串,即
def hash(key):
return key[0]+key[-1]
但這種演算法對索引字元的要求非常高,至少頭尾不能重複。所以,現在需要能把超長字串對映成特定短字串而且盡量避免重複的演算法。
最簡單的雜湊函式就是求餘,將輸入字串按位轉為整數之後求餘。由於在字串可能會轉成非常大的整數,故需了解餘數的性質
(a+b)%c=(a%c+b %c)% c
相應地有:
(a*b)%c=((a%c)*(b %c))% c
用c語言實現如下:
#include
#define maxhash 100
//快速取冪法,a*b^n%c
int powermod (int a, i程式設計客棧nt b, int n, int c)
return (a*ans)%c;
}int hash(char* key, int n)
return addr%maxhash;
}int main()
printf("%d\n",hash(str,i));
} return 0;
}測試如下:
>gcc hash.c
>a.exe
asdf
21microcold
81tinycold
12microcool
5minicool
81minicold
73儘管minicool和microcold撞車了,但通過100以內的位數,去表示52的9次方 的樣本,也算是不錯的表現了。
為了不發生撞車,則需更改陣列中的元素型別——至少得是個結構體。而防止撞車的方法很簡單,如果發生撞車,那我就不雜湊了,直接發配到乙個指定的陣列中。
#include
#include
#include
#define maxhash 100
typedef struct hashnode *hashnode;
struct hashnode* hashtable[maxhash];
struct hashnode* crashtable[maxhash]; //儲存撞擊之後的值
int numcrash=0; //已有的撞擊值
void inittable()
}void insertcrash(char* str, int index, int n)
else
}//n為字串長度
void inserthash(char* str, int index,int n)else
}void printhash()
}int powermod (int a, int b, int n, int c)
return (a*ans)%c;
}int hash(char* key, int n)
return addr%maxhash;
}int main()
inserthash(str,hash(str,i),i);
printf("%d\n",hash(str,i));
} printhash();
return 0;
}最後得到:
>gcc hash.c
>a.exe
asdf
21hellworld
84microcold
81minicool
81tinycool
20tinycold
12weixiaoleng
11gfmdbv
exit
crashtable[0]:minicool
hashtable[11]:weixiaoleng
hashtable[12]:tinycold
hashtable[20]:tinycool
hashtable[21]:asdf
hashtable[81]:microcold
hashtable[84]:hellworld
可見一方面的確雜湊了,另一方面也的確防撞了。
教你從零開始寫乙個雜湊表 雜湊函式
在這一節,我們來編寫雜湊函式。我們選擇的雜湊函式應該具有 以下特性 我們使用的是常見的字串雜湊函式,偽 的表達如下 function hash string,a,num buckets hash 0 string len length string for i 0,1,string len hash...
教你從零開始寫乙個雜湊表 雜湊衝突
雜湊函式把乙個無窮大的輸入集合對映到乙個有限大小的輸出集合。不同的關鍵字可能會被對映到同乙個陣列下標,如此一來就導致了雜湊衝突。雜湊表必須實現解決衝突的方法。我們的雜湊表將使用開放位址法和再雜湊法。在桶索引衝突後,再雜湊法會使用兩個雜湊函式來計算鍵值對將要儲存的桶索引值。有關其他雜湊衝突的解決方法,...
C語言寫乙個類
ifndef 50 2 h define 50 2 h typedef void demo demo demo create int i,int j int demo geti demo pthis int demo getj demo pthis int demo add demo pthis,i...