日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Hash Table

發布時間:2024/3/12 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Hash Table 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

數據結構:hash_map原理?
這是一節讓你深入理解hash_map的介紹,如果你只是想囫圇吞棗,不想理解其原理,你倒是可以略過這一節,但我還是建議你看看,多了解一些沒有壞處。

hash_map基于hash table(哈希表)。哈希表最大的優點,就是把數據的存儲和查找消耗的時間大大降低,幾乎可以看成是常數時間;而代價僅僅是消耗比較多的內存。然而在當前可利用內存越來越多的情況下,用空間換時間的做法是值得的。另外,編碼比較容易也是它的特點之一。

其基本原理是:使用一個下標范圍比較大的數組來存儲元素。可以設計一個函數(哈希函數,也叫做散列函數),使得每個元素的關鍵字都與一個函數值(即數組下標,hash值)相對應,于是用這個數組單元來存儲這個元素;也可以簡單的理解為,按照關鍵字為每一個元素分類,然后將這個元素存儲在相應所對應的地方,稱為桶。

但是,不能夠保證每個元素的關鍵字與函數值是一一對應的,因此極有可能出現對于不同的元素,卻計算出了相同的函數值,這樣就產生了沖突,換句話說,就是把不同的元素分在了相同的之中。?總的來說,直接定址解決沖突是哈希表的兩大特點。

hash_map,首先分配一大片內存,形成許多桶。是利用hash函數,對key進行映射到不同區域(桶)進行保存。

其插入過程是:

1.?得到key
2.?
通過hash函數得到hash

3.?得到桶號(一般都為hash值對桶數求模)
4.?
存放keyvalue在桶內。

其取值過程是:

1.?得到key
2.?
通過hash函數得到hash

3.?得到桶號(一般都為hash值對桶數求模)
4.?
比較桶的內部元素是否與key相等,若都不相等,則沒有找到。

5.?取出相等的記錄的value。

hash_map中直接地址用hash函數生成,解決沖突,用比較函數解決。這里可以看出,如果每個桶內部只有一個元素,那么查找的時候只有一次比較。當許多桶內沒有值時,許多查詢就會更快了(指查不到的時候).

由此可見,要實現哈希表,?和用戶相關的是:hash函數和比較函數。這兩個參數剛好是我們在使用hash_map時需要指定的參數。

來源:??http://www.stlchina.org/twiki/bin/view.pl/Main/STLDetailHashMap

?

一個實現

/**PROGRAM :哈希表的綜合操作?**/

/**CONTENT :Insert,Search,Deltet **/

/* * * * * * * * * * * * * * * * * * * * * * * **/

#include <math.h>

#include <stdio.h>

#include <stdlib.h>

#define MAXSIZE 30 /*哈希表的最大容量,與所采用的哈希函數有關*/

typedef enum{False,True}??BOOL;

typedef enum{NULLKEY,HAVEKEY,DELKEY} HAVEORNOT;

/*哈希表元素的三種狀態,沒有記錄、有記錄、有過記錄但已被刪除*/

typedef struct /*定義哈希表的結構*/

{

int elem[MAXSIZE]; /*?數據元素體?*/

HAVEORNOT elemflag[MAXSIZE]; /*元素狀態標志,沒有記錄、有記錄、有過記錄但已被刪除*/

int count; /*哈希表中當前元素的個數?*/

}HashTable;

typedef struct

{int keynum; /*記錄的數據域,只有關鍵字一項*/

}Record;

void InitialHash(HashTable*); /*初始化哈希表*/

void CreateHash(HashTable*);/*?根據從鍵盤上輸入的一系列整數建立哈希表?*/

void PrintHash(HashTable); /*顯示哈希表中的所有元素*/

BOOL SearchHash(HashTable,int,int*); /*在哈希表中查找元素*/

BOOL InsertHash(HashTable*,Record); /*在哈希表中插入元素*/

BOOL DeleteHash(HashTable*,Record); /*在哈希表中刪除元素*/

int Hash(int); /*哈希函數*/

?

void main()

{

???????HashTable H; /*聲明哈希表H*/

???????char ch,j='y';

???????int position;

???????Record R;

???????BOOL temp;

???????//textbackground(3); /*設定屏幕顏色*/

???????//textcolor(15);

???????//clrscr();

???????InitialHash(&H);

???????CreateHash(&H);

???????/*-------------------------程序說明-------------------------------*/

???????printf("This program will show how to operate to a HashTable./n");

???????printf("You can display all elems,search a elem,/ninsert a elem,delete a elem./n");

???????/*----------------------------------------------------------------*/

?

???????while(j!='n')

???????{

??????????????printf("1.display/n");

??????????????printf("2.search/n");

??????????????printf("3.insert/n");

??????????????printf("4.delete/n");

??????????????printf("5.exit/n");

??????????????scanf(" %c",&ch); /*輸入操作選項*/

??????????????switch(ch)

??????????????{

??????????????case '1':if(H.count) PrintHash(H); /*哈希表不空*/

?????????????????????else printf("The HashTable has no elem!/n");

?????????????????????break;

??????????????case '2':if(!H.count) printf("The HashTable has no elem!/n"); /*哈希表空*/

?????????????????????else

?????????????????????{printf("Please input the keynum(int) of the elem to search:");

?????????????????????scanf("%d",&R.keynum); /*輸入待查記錄的關鍵字*/

?????????????????????temp=SearchHash(H,R.keynum,&position);

?????????????????????/*temp=True:記錄查找成功;temp=False:沒有找到待查記錄*/

?????????????????????if(temp) printf("The position of the elem is %d/n",position);

?????????????????????else printf("The elem isn't exist!/n");

?????????????????????}

?????????????????????break;

??????????????case '3':if(H.count==MAXSIZE) /*哈希表已滿*/

?????????????????????{printf("The HashTable is full!/n");

?????????????????????break;

?????????????????????}

?????????????????????printf("Please input the elem(int) to insert:");

?????????????????????scanf("%d",&R.keynum); /*輸入要插入的記錄*/

?????????????????????temp=InsertHash(&H,R);

?????????????????????/*temp=True:記錄插入成功;temp=False:已存在關鍵字相同的記錄*/

?????????????????????if(temp) printf("Sucess to insert the elem!/n");

?????????????????????else printf("Fail to insert the elem.The same elem has been exist!/n");

?????????????????????break;

??????????????case '4':printf("Please input the keynum of the elem(int) to delet:");

?????????????????????scanf("%d",&R.keynum); /*輸入要刪除記錄的關鍵字*/

?????????????????????temp=DeleteHash(&H,R);

?????????????????????/*temp=True:記錄刪除成功;temp=False:待刪記錄不存在?*/

?????????????????????if(temp) printf("Sucess to delete the elem!/n");

?????????????????????else printf("The elem isn't exist in the HashTable!/n");

?????????????????????break;

??????????????default: j='n';

??????????????}

???????}

???????printf("The program is over!/nPress any key to shut off the window!/n");

???????getchar();

}

?

void InitialHash(HashTable *H)

{/*哈希表初始化*/

???????int i;

???????(*H).count=0;

???????for(i=0;i<MAXSIZE;i++) (*H).elemflag[i]=NULLKEY;

}

?

void CreateHash(HashTable *H)

{/*?根據從鍵盤上輸入的一系列整數(不超過12個,以-1結束)建立哈希表?*/

?Record e;

?printf("請輸入的一系列整數(不超過12個,以-1結束)以建立哈希表:/n");

?scanf("%d",&e.keynum);

?while(e.keynum!=-1)

????if(InsertHash(H,e))??scanf("%d",&e.keynum);

????else

??????{printf("請輸入不重復的數據!");

???????return;

???????}????

}

?

void PrintHash(HashTable H)

{?????/*顯示哈希表所有元素及其所在位置*/

???????int i;

???????for(i=0;i<MAXSIZE;i++) /*顯示哈希表中記錄所在位置*/

???????if(H.elemflag[i]==HAVEKEY) /*只顯示標志為HAVEKEY(存放有記錄)的元素*/

???????printf("%-4d",i);

???????printf("/n");

???????for(i=0;i<MAXSIZE;i++) /*顯示哈希表中記錄值*/

???????if(H.elemflag[i]==HAVEKEY)

???????printf("%-4d",H.elem[i]);

???????printf("/ncount:%d/n",H.count); /*顯示哈希表當前記錄數*/

}

?

BOOL SearchHash(HashTable H,int k,int *p)

{/*在開放定址哈希表H中查找關鍵字為k的數據元素,若查找成功,以p指示

待查數據元素在表中的位置,并返回True;否則,以p指示插入位置,并

返回False*/

???????int p1;

???????p1=(*p)=Hash(k); /*求得哈希地址*/

???????while(H.elemflag[(*p)]==HAVEKEY&&k!=H.elem[(*p)])

???????/*該位置中填有記錄并且關鍵字不相等*/

???????{

??????????????(*p)++; /*沖突處理方法:線性探測再散列*/

??????????????if((*p)>=MAXSIZE) (*p)=(*p)%MAXSIZE; /*循環搜索*/

??????????????if((*p)==p1) return False; /*整個表已搜索完,沒有找到待查元素*/

???????}

???????if(k==H.elem[(*p)]&&H.elemflag[(*p)]==HAVEKEY) /*查找成功,p指示待查元素位置*/

??????????????return True;

???????else return False; /*查找不成功*/

}

?

BOOL InsertHash(HashTable *H,Record e)

{/*查找不成功時插入元素e到開放定址哈希表H中,并返回True,否則返回False*/

???????int p;

???????if(SearchHash((*H),e.keynum,&p)) /*表中已有與e有相同關鍵字的元素*/

???????return False;

???????else

???????{(*H).elemflag[p]=HAVEKEY; /*設置標志為HAVEKEY,表示該位置已有記錄*/

???????(*H).elem[p]=e.keynum; /*插入記錄*/

???????(*H).count++; /*哈希表當前長度加一?*/

???????return True;

???????}

}

?

BOOL DeleteHash(HashTable *H,Record e)

{/*在查找成功時刪除待刪元素e,并返回True,否則返回False*/

???????int p;

???????if(!SearchHash((*H),e.keynum,&p)) /*表中不存在待刪元素*/

???????return False;

???????else

???????{(*H).elemflag[p]=DELKEY; /*設置標志為DELKEY,表明該元素已被刪除*/

???????(*H).count--; /*哈希表當前長度減一*/

???????return True;

???????}

}

?

int Hash(int kn)

{/*哈希函數:H(key)=key MOD 11*/

???????return (kn%11);

}?

?

?

//code2:

///

哈希表的設計主要是設計哈希函數 哈希函數:將關鍵字映射到哈希表的位置 哈希函數的建立有五種常見方法: 1. 除余法 2.折疊法 3.平方取中法 4.提取法 5. 基數轉換法 哈希沖突解決方法 1. 開放定址法 開放定址法又分為線性探查法,二次探查法,雙散列函數探查法 2.再哈希法 3.鏈地址法 4.建立一個公共溢出區 可擴展文件的散列函數 1.可擴展散列 2.線性散列哈希程序示例: 沖突解決方法為:雙散列函數探查法 哈希函數關鍵字為:人名字母ASCII相加 哈希函數為:關鍵字%M,從而映射到哈希表中的位置 代碼:#include<stdio.h> #include<conio.h> #define HASH_LEN 50 //哈希表的長度 #define M 47 //隨機數 #define NAME_NO 30 //人名的個數 typedef struct { char *py; //名字的拼音 int k; //拼音所對應的整數 }NAME; NAME NameList[HASH_LEN]; //全局變量NAME typedef struct //哈希表 { char *py; //名字的拼音 int k; //拼音所對應的整數 int si; //查找長度 }HASH; HASH HashList[HASH_LEN]; //全局變量HASH void InitNameList() //姓名(結構體數組)初始化 { char *f; int r,s0,i; NameList[0].py="wanghui"; NameList[1].py="mayuelong"; NameList[2].py="chenzhicheng"; NameList[3].py="sunpeng"; NameList[4].py="zengqinghui"; NameList[5].py="liqingbo"; NameList[6].py="liujunpeng"; NameList[7].py="jiangquanlei"; NameList[8].py="xingzhengchuan"; NameList[9].py="luzhaoqian"; NameList[10].py="gaowenhu"; NameList[11].py="zhuhaoyin"; NameList[12].py="chenlili"; NameList[13].py="wuyunyun"; NameList[14].py="huangjuanxia"; NameList[15].py="wangyan"; NameList[16].py="zhoutao"; NameList[17].py="jiangzhenyu"; NameList[18].py="liuxiaolong"; NameList[19].py="wangziming"; NameList[20].py="fengjunbo"; NameList[21].py="lilei"; NameList[22].py="wangjia"; NameList[23].py="zhangjianguo"; NameList[24].py="zhuqingqing"; NameList[25].py="huangmin"; NameList[26].py="haoyuhan"; NameList[27].py="zhoutao"; NameList[28].py="zhujiang"; NameList[29].py="lixiaojun"; for (i=0;i<NAME_NO;i++) {s0=0;f=NameList[i].py; for (r=0;*(f+r)!='\0';r++)s0=*(f+r)+s0; NameList[i].k=s0; } } void CreateHashList() //建立哈希表 {int i;for (i=0; i<HASH_LEN;i++){HashList[i].py="";HashList[i].k=0;HashList[i].si=0;} for (i=0;i<HASH_LEN;i++){int sum=0;int adr=(NameList[i].k)%M; //哈希函數int d=adr;if(HashList[adr].si==0) //如果不沖突{HashList[adr].k=NameList[i].k;HashList[adr].py=NameList[i].py;HashList[adr].si=1;}else //沖突{do{d=(d+NameList[i].k%10+1)%M; //偽隨機探測再散列法處理沖突 sum=sum+1; //查找次數加1 }while (HashList[d].k!=0);HashList[d].k=NameList[i].k;HashList[d].py=NameList[i].py;HashList[d].si=sum+1;}}} void FindList() //查找 {char name[20]={0};int s0=0,r,sum=1,adr,d; printf("\n請輸入姓名的拼音:"); scanf("%s",name); for (r=0;r<20;r++) //求出姓名的拼音所對應的整數(關鍵字)s0+=name[r]; adr=s0%M; //使用哈希函數 d=adr; if(HashList[adr].k==s0) //分3種情況進行判斷printf("\n姓名:%s 關鍵字:%d 查找長度為: 1",HashList[d].py,s0); else if (HashList[adr].k==0)printf("無此記錄!"); else {int g=0;do{d=(d+s0%10+1)%M; //偽隨機探測再散列法處理沖突 sum=sum+1;if (HashList[d].k==0){printf("無此記錄! ");g=1; }if (HashList[d].k==s0){ printf("\n姓名:%s 關鍵字:%d 查找長度為:%d",HashList[d].py,s0,sum);g=1;}}while(g==0); } } void Display() // 顯示哈希表 {int i; float average=0;printf("\n\n地址\t關鍵字\t\t搜索長度\tH(key)\t 姓名\n"); //顯示的格式for(i=0; i<50; i++) {printf("%d ",i);printf("\t%d ",HashList[i].k);printf("\t\t%d ",HashList[i].si);printf("\t\t%d ",HashList[i].k%M);printf("\t %s ",HashList[i].py);printf("\n"); } for (i=0;i<HASH_LEN;i++) average+=HashList[i].si; average/=NAME_NO; printf("\n\n平均查找長度:ASL(%d)=%f \n\n",NAME_NO,average); }void main() {char ch1; printf("\n 哈希表的建立和查找\n");printf(" *-------------------------------------------*\n");printf(" | D. 顯示哈希表 |\n");printf(" | F. 查找 |\n");printf(" | Q. 退出 |\n");printf(" *-------------------------------------------*\n");InitNameList(); CreateHashList (); while(1) { printf("\n Option-:"); fflush(stdin);ch1=getchar();if (ch1=='D'||ch1=='d')Display(); else if (ch1=='F'||ch1=='f')FindList();else if (ch1=='Q'||ch1=='q')return;else{printf("\n請輸入正確的選擇!");}}}程序示例2: #include <math.h> #include <stdio.h> #include <stdlib.h> #define MAXSIZE 30 typedef enum{False,True} BOOL; typedef enum{NULLKEY,HAVEKEY,DELKEY} HAVEORNOT;typedef struct { int elem[MAXSIZE]; HAVEORNOT elemflag[MAXSIZE]; int count; }HashTable; typedef struct {int keynum; }Record; void InitialHash(HashTable*); void CreateHash(HashTable*); void PrintHash(HashTable); BOOL SearchHash(HashTable,int,int*); BOOL InsertHash(HashTable*,Record); BOOL DeleteHash(HashTable*,Record); int Hash(int);void main() {HashTable H;char ch,j='y';int position;Record R;BOOL temp;//textbackground(3);//textcolor(15);//clrscr();InitialHash(&H);CreateHash(&H);printf("This program will show how to operate to a HashTable.\n");printf("You can display all elems,search a elem,\ninsert a elem,delete a elem.\n");while(j!='n'){printf("1.display\n");printf("2.search\n");printf("3.insert\n");printf("4.delete\n");printf("5.exit\n");scanf(" %c",&ch);switch(ch){case '1':if(H.count) PrintHash(H);else printf("The HashTable has no elem!\n");break;case '2':if(!H.count) printf("The HashTable has no elem!\n");else{printf("Please input the keynum(int) of the elem to search:");scanf("%d",&R.keynum);temp=SearchHash(H,R.keynum,&position);if(temp) printf("The position of the elem is %d\n",position);else printf("The elem isn't exist!\n");}break;case '3':if(H.count==MAXSIZE){printf("The HashTable is full!\n");break;}printf("Please input the elem(int) to insert:");scanf("%d",&R.keynum);temp=InsertHash(&H,R);if(temp) printf("Sucess to insert the elem!\n");else printf("Fail to insert the elem.The same elem has been exist!\n");break;case '4':printf("Please input the keynum of the elem(int) to delet:");scanf("%d",&R.keynum);temp=DeleteHash(&H,R);if(temp) printf("Sucess to delete the elem!\n");else printf("The elem isn't exist in the HashTable!\n");break;default: j='n';}}printf("The program is over!\nPress any key to shut off the window!\n");getchar(); }void InitialHash(HashTable *H) {int i;(*H).count=0;for(i=0;i<MAXSIZE;i++) (*H).elemflag[i]=NULLKEY; }void CreateHash(HashTable *H) { Record e; printf("請輸入的一系列整數(不超過12個,以-1結束)以建立哈希表:\n"); scanf("%d",&e.keynum); while(e.keynum!=-1)if(InsertHash(H,e))scanf("%d",&e.keynum);else{printf("請輸入不重復的數據!");return;} }void PrintHash(HashTable H) { int i;for(i=0;i<MAXSIZE;i++)if(H.elemflag[i]==HAVEKEY)printf("%-4d",i);printf("\n");for(i=0;i<MAXSIZE;i++)if(H.elemflag[i]==HAVEKEY)printf("%-4d",H.elem[i]);printf("\ncount:%d\n",H.count); }BOOL SearchHash(HashTable H,int k,int *p) {int p1;p1=(*p)=Hash(k);while(H.elemflag[(*p)]==HAVEKEY&&k!=H.elem[(*p)]){(*p)++;if((*p)>=MAXSIZE) (*p)=(*p)%MAXSIZE;if((*p)==p1) return False;}if(k==H.elem[(*p)]&&H.elemflag[(*p)]==HAVEKEY)return True;else return False; }BOOL InsertHash(HashTable *H,Record e) {int p;if(SearchHash((*H),e.keynum,&p))return False;else{(*H).elemflag[p]=HAVEKEY;(*H).elem[p]=e.keynum;(*H).count++;return True;} }BOOL DeleteHash(HashTable *H,Record e) {int p;if(!SearchHash((*H),e.keynum,&p))return False;else{(*H).elemflag[p]=DELKEY;(*H).count--;return True;} }int Hash(int kn) {return (kn%11); }


?

總結

以上是生活随笔為你收集整理的Hash Table的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲激情一区二区 | 99re这里有精品 | 亚洲欧美国产一区二区三区 | 邻家有女4完整版电影观看 欧美偷拍另类 | 欧美黑人精品一区二区 | 老司机免费视频 | 动漫大乳美女 | 免费看的av片 | 羞视频在线观看 | 久久久精品影院 | 亚洲精品免费在线 | 国产精品成人一区二区网站软件 | 免费视频一二三区 | 日韩成人片 | 激情www | 中文字幕乱码一二三区 | 奇米影视第四色777 波多野结衣一区二区三区免费视频 | 超碰在线人人草 | 久久国产一| 国产精品毛片久久久久久 | 国产伦精品一区二区三区视频1 | 丝袜高跟av | 欧美性天天影院 | 亚洲一区二区三区四区五区xx | 人妖一区 | 91精品视频免费看 | 亚洲一区二区三区在线播放 | 一区二区三区网站 | 欧美亚洲色综久久精品国产 | 高清久久久 | 国产伦精品 | 国产特级黄色录像 | 亚洲人xxx | 涩涩视频免费 | 欧美亚洲一区二区三区四区 | 在线成人黄色 | 中文字幕亚洲在线 | 伊人久久久久久久久久久久久 | av一区在线观看 | 国内自拍av | 日日夜夜免费 | 秋霞电影一区二区 | 网站黄在线观看 | 视频二区中文字幕 | 男人添女人下部高潮视频 | 日本少妇激情舌吻 | 色欲人妻综合网 | 久久99精品久久久久久水蜜桃 | 日本激情视频在线 | 国产精品伦一区二区三级古装电影 | 日韩中文字幕综合 | 性久久久久 | 亚洲一区二区精品在线观看 | 在线电影一区二区 | 久久精品综合网 | 成人精品区 | 精品乱子伦一区二区三区 | 97香蕉碰碰人妻国产欧美 | 成人精品视频一区 | 99热这里只有精品9 日韩综合在线 | 老湿机69福利 | 欧美一区二区三区不卡视频 | 国产亚洲精品精品精品 | 亚洲av永久无码精品一区二区国产 | jizz成熟丰满日本少妇 | 99久久久国产精品无码性 | 国产人妻黑人一区二区三区 | 在线免费观看成年人视频 | 丰满熟妇被猛烈进入高清片 | 噜噜av| 色狠狠一区二区三区香蕉 | aaa黄色一级片 | 亚洲成人av电影网站 | 国产精品--色哟哟 | 国产三级av片 | 亚洲三级在线看 | 超碰在线公开 | 超碰在线中文 | 91福利一区 | 日本天堂网在线观看 | 性调教学院高h学校 | 超碰免费视| 日本国产在线播放 | 中文字幕一区二区视频 | 鲁一鲁一鲁一鲁一av | 9.1成人看片免费版 日韩经典在线 | 日本少妇xxx | 露脸啪啪清纯大学生美女 | 爱爱视频在线看 | 制服诱惑一区二区 | 日韩永久免费视频 | 黄色片网站视频 | 久久三级 | 一级片亚洲 | 日韩av黄色片 | 毛片网站在线播放 | www.免费av | 午夜有码| 一本大道东京热无码 |