C語(yǔ)言寫(xiě)一個(gè)散列表_第1頁(yè)
C語(yǔ)言寫(xiě)一個(gè)散列表_第2頁(yè)
C語(yǔ)言寫(xiě)一個(gè)散列表_第3頁(yè)
C語(yǔ)言寫(xiě)一個(gè)散列表_第4頁(yè)
C語(yǔ)言寫(xiě)一個(gè)散列表_第5頁(yè)
已閱讀5頁(yè),還剩2頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第C語(yǔ)言寫(xiě)一個(gè)散列表目錄一、快速理解散列表二、散列函數(shù)三、防撞

一、快速理解散列表

散列表,就是下標(biāo)可以為字母的數(shù)組。

假設(shè)現(xiàn)有一個(gè)數(shù)組inta[100],想查找其中第40個(gè)元素,則直接輸入a[40]就可以了,時(shí)間復(fù)雜度為O(1)O(1)O(1)。

問(wèn)題在于,當(dāng)下標(biāo)不是數(shù)字,而是一個(gè)字符串的時(shí)候,可能需要一個(gè)超大的空間才能將所有下標(biāo)妥善地存放在特定的位置。例如,若以大小寫(xiě)字母作為下標(biāo)索引,那么一位就需要預(yù)留52個(gè)空間,10位就需要52的10次方這么大的空間,根本沒(méi)有設(shè)備可以滿(mǎn)足。

好在,52的10次方這么龐大的數(shù)字也超出了正常人的使用范圍,無(wú)論多長(zhǎng)的索引,我們能用上的值也絕對(duì)是有限的。

例如,現(xiàn)有下面三個(gè)字符串作為下標(biāo)

key1="microcold";

key2="tinycold";

key3="microcool";

其實(shí)只需要選取頭、尾兩個(gè)字母,就能很好地區(qū)分這三個(gè)字符串,即

defhash(key):

returnkey[0]+key[-1]

但這種算法對(duì)索引字符的要求非常高,至少頭尾不能重復(fù)。所以,現(xiàn)在需要能把超長(zhǎng)字符串映射成特定短字符串而且盡量避免重復(fù)的算法。

二、散列函數(shù)

最簡(jiǎn)單的散列函數(shù)就是求余,將輸入字符串按位轉(zhuǎn)為整數(shù)之后求余。由于在字符串可能會(huì)轉(zhuǎn)成非常大的整數(shù),故需了解余數(shù)的性質(zhì)

(a+b)%c=(a%c+b%c)%c

相應(yīng)地有:

(a*b)%c=((a%c)*(b%c))%c

用C語(yǔ)言實(shí)現(xiàn)如下:

#includestdio.h

#defineMAXHASH100

//快速取冪法,a*b^n%c

int

PowerMod(inta,intb,intn,intc)

int

ans=1;

b=b%c;

while(n0){

if(n%2==1)

ans=(ans*b)%c;

n=n/2;

//b=1;

b=(b*b)%c;

}

return(a*ans)%c;

inthash(char*key,intn){

intaddr=0;

for(inti=0;ii++){

addr+=PowerMod(key[i],128,i,MAXHASH);

}

returnaddr%MAXHASH;

intmain(){

char*str;

inti;

while(1){

gets(str);

i=0;

while(str[i++]!='\0'){}

printf("%d\n",hash(str,i));

}

return0;

}

測(cè)試如下:

gcchash.c

a.exe

microcold

tinycold

microcool

minicool

minicold

73

三、防撞

盡管minicool和microcold撞車(chē)了,但通過(guò)100以?xún)?nèi)的位數(shù),去表示52的9次方的樣本,也算是不錯(cuò)的表現(xiàn)了。

為了不發(fā)生撞車(chē),則需更改數(shù)組中的元素類(lèi)型至少得是個(gè)結(jié)構(gòu)體。而防止撞車(chē)的方法很簡(jiǎn)單,如果發(fā)生撞車(chē),那我就不散列了,直接發(fā)配到一個(gè)指定的數(shù)組中。

#includestdio.h

#includestdlib.h

#includestring.h

#defineMAXHASH100

typedefstructHASHNODE{

char*key;

intnext;

}*hashNode;

structHASHNODE*hashTable[MAXHASH];

structHASHNODE*crashTable[MAXHASH];

//存儲(chǔ)撞擊之后的值

intnumCrash=0;

//已有的撞擊值

voidinitTable(){

for(inti=0;iMAXHASH;i++){

hashTable[i]=(hashNode)malloc(sizeof(structHASHNODE));

hashTable[i]-key=NULL;

hashTable[i]-next=-1;

crashTable[i]=(hashNode)malloc(sizeof(structHASHNODE));

crashTable[i]-key=NULL;

hashTable[i]-next=-1;

}

voidinsertCrash(char*str,intindex,intn){

if(index==numCrash){

crashTable[numCrash]-key=(char*)malloc(sizeof(char)*n);

strcpy(crashTable[numCrash++]-key,str);

//此時(shí)新增一個(gè)節(jié)點(diǎn)

}

else{

if(crashTable[index]-next==-1)

crashTable[index]-next=numCrash;

insertCrash(str,hashTable[index]-next,n);

}

//n為字符串長(zhǎng)度

voidinsertHash(char*str,intindex,intn){

if(hashTable[index]-key==NULL){

hashTable[index]-key=(char*)malloc(sizeof(char)*n);

strcpy(hashTable[index]-key,str);

}else{

if(hashTable[index]-next==-1)

hashTable[index]-next=numCrash;

insertCrash(str,hashTable[index]-next,n);

}

voidprintHash(){

for(inti=0;iMAXHASH;i++){

if(hashTable[i]-key!=NULL)

printf("hashTable[%d]:%s\n",i,hashTable[i]-key);

if(crashTable[i]-key!=NULL)

printf("crashTable[%d]:%s\n",i,crashTable[i]-key);

}

int

PowerMod(inta,intb,intn,intc)

int

ans=1;

b=b%c;

while(n0){

if(n%2==1)

ans=(ans*b)%c;

n=n/2;

//b=1;

b=(b*b)%c;

}

return(a*ans)%c;

inthash(char*key,intn){

intaddr=0;

for(inti=0;ii++){

addr+=PowerMod(key[i],128,i,MAXHASH);

}

returnaddr%MAXHASH;

intmain(){

initTable();

char*str;

inti;

while(1){

gets(str);

if(strcmp(str,"exit")==0)break;

i=0;

while(str[i++]!='\0'){}

insertHash(str,hash(str,i),i);

printf("%d\n",hash(str,i));

}

printHash();

return0;

}

最后得到:

gcchash.c

a.exe

hellworld

microcold

minicool

tinycool

ti

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論