實習報告 題目:設計一個哈希表,完成相應的建表和查表程序 班級:1503013 姓名:李睿元 學號:15030130073 完成日期:2016.12.04
一、 需求分析
1. 假設人名為中國人名的漢語拼音形式;
2. 待填入哈希表的姓名共有 30 個,去平均查找長度的上限為 2;
3. 哈希函數用除留余數法構造,用偽隨機探測再散列法處理沖突;
4. 取讀者周圍較熟悉的 30 個人的姓名。
二、 概要設計
1. 抽象數據類型的定義:
(1)人名數據表:
typedef struct Node
{
char name[20];
int key;
}Node,NodeList[MAX];
(2)哈希表:
typedef struct hashtable {
char* name;
int key;
int conflict_time; }HashTable[hashlen]; (3)變量:
#define P 61//隨機數值
#define MAX 30//人數
#define hashlen 61//哈希表長
2. 主要函數的實現:
(1)哈希函數:
int Hash(int key) (2)關鍵字獲得:
int GetKey(char str[])
(3)文件流中讀取姓名:
void GetName(NodeList &L,int i,FILE* fp) (4)哈希表的初始化:
void InitialHashTable(HashTable &ht) (5)偽隨機探測序列的生成:
void CreatConfilctArray(int n[]) (6)哈希表的生成:
void CreatHashTable(HashTable &ht,NodeList L,int* n) (7)哈希表的查詢:
void SearchHashTable(HashTable ht,int* n,char get_name[]) 三、 詳細設計 #include <stdio.h> #include <stdlib.h> #include <string.h>
#define P 61//隨機數值
#define MAX 30//人數
#define hashlen 61//哈希表長
typedef struct Node {
char name[20];
int key;
}Node,NodeList[MAX]; typedef struct hashtable {
char* name;
int key;
int conflict_time; }HashTable[hashlen];
int Hash(int key) {
return key%P;
}
int GetKey(char str[]) {
int t=0;
char *s=str;
while(*s)
{
t += *s;
s++;
}
return t;
}
void GetName(NodeList &L,int i,FILE* fp) { /* printf("請以拼音形式輸入第%d 個姓名:",i);
scanf("%s",L[i].name);
L[i].key=GetKey(L[i].name); */
fscanf(fp,"%s",L[i].name);
L[i].key=GetKey(L[i].name);
//printf("\n"); }
void InitialHashTable(HashTable &ht) {
int n=0;
while(n<hashlen)
{
ht[n].conflict_time=0;
ht[n].name=NULL;
ht[n].key=0;
n++;
} }
void CreatConfilctArray(int n[]) { // n=(int*)malloc(50*sizeof(int));
int i=0,j=0;
while(i<50)
{
n[i]=rand()%(hashlen+1);
for(;j<i;j++)
{
if(n[i]==n[j])
{
j=0;
n[i]=rand()%(hashlen+1);
continue;
}
}
i++;
} }
void CreatHashTable(HashTable &ht,NodeList L,int* n) { // CreatConfilctArray(n);
int i=0;
int t;
while(i<MAX)
{
t=Hash(L[i].key);
if(ht[t].conflict_time==0)
{
ht[t].name=L[i].name;
ht[t].conflict_time++;
ht[t].key=L[i].key;
printf("姓名:%s key 值:%d 表內存儲位置:%d\n",L[i].name,L[i].key,t);
}
else
{
int m=0;
int d=(t+n[m])%hashlen;
while(ht[d].conflict_time!=0)
{
ht[d].conflict_time++;
m++;
d=(t+n[m])%hashlen;
}
ht[d].name=L[i].name;
ht[d].conflict_time++;
ht[d].key=L[i].key;
printf("姓名:%s key 值:%d 表內存儲位置:%d\n",L[i].name,L[i].key,d);
}
i++;
} }
void SearchHashTable(HashTable ht,int* n,char get_name[]) {
//printf("請輸入要查詢的姓名:");
//char get_name[20];
int p=-1;
int s_time=1;
// scanf("%s",get_name);
int h,k;
int t;
k=GetKey(get_name);
t=h=Hash(k);
while(1)
{
/*if(ht[h].conflict_time==0&&ht[h].key!=k)
{
printf("表中未找到無此人!\n");
break;
}
else if(ht[h].key==k)
{
printf("已找到%s,表內存儲位置:%d\n",get_name,h);
break;
}
else
{
p++;
h=n[p];
}*/
if(ht[h].name==NULL)
{
printf("表中未找到無此人!\n");
break;
}
else if(strcmp(ht[h].name,get_name)==0)
{
printf("已找到%s,表內存儲位置:%d,查找次數:%d\n",get_name,h,s_time);
break;
}
else
{
p++;
h=(t+n[p])%hashlen;
s_time++;
}
} }
int main()
{ // printf("請輸入建表所需的三十個人名!\n");
int i,j;
NodeList L;
HashTable ht;
InitialHashTable(ht);
char get_name[20]={0};
int rand_n[50];
CreatConfilctArray(rand_n);
FILE* fp;
fp=fopen("name.txt","r");
for(i=0;i<30;i++)
{
GetName(L,i,fp);
}
fclose(fp);
CreatHashTable(ht,L,rand_n);
printf("\n");
printf("--------------哈希表建表完成-------------");
printf("\n");
while(1)
{
get_name[20]={0};
printf("請輸入要查找的人名(輸入“***”表示結束程序):");
scanf("%s",get_name);
printf("關鍵字:%d ",GetKey(get_name));
if(strcmp(get_name,"***")==0)
break;
SearchHashTable(ht,rand_n,get_name);
}
return 0; } 四、 調試分析
1. 哈希表可以在理想情況下不經過任何比較,一次存取就能得到所查記錄;
2. 除留余數法對于 p 的選擇很重要,經過分析后的選擇是 p 為小于等于 m 的最大素數,最終選擇了 61;
3. 偽隨機探測再散列相較于線性探測再散列或二次探測再散能有效的防止二次堆積。
五、 用戶手冊
1. 本程序的運行環境為 Windows 操作系統,執行文件為 hashtable.exe;
2. 本程序的輸入的名字存儲在 name.txt 文件中;
3.
程序進入后已經完成哈希表的構建并進行展示,用戶只需進行相應的查找;
六、 測試數據
1. 挑選表中已有的十個姓名進行測試 (xiaoli,zhuangshuangshuang,laobai,lujia,xiaohei,huyazhou,abao,haojie,taosiji,wangkun)
與上方的哈希表進行對比完全匹配。
2. 選擇 5 個沒有在表中的名字進行查表操作:
(lovetianqi,tianjiejie,jiwang,beijing,heheda)
推薦訪問: 實驗 報告 哈希表同志們:今天這個大會,是市委全面落實黨要管黨、從嚴治黨要求的一項重大舉措,也是對縣市區委書記履行基層黨建工作第一責任人情況的一次集中檢閱,同時是對全市基層黨建工作的一次再部署、再落實的會議。前面,**
***年,我認真履行領班子、帶隊伍、抓黨員、保穩定的基層黨建工作思路,以學習貫徹習近平新時代中國特色社會主義思想和黨的十九大歷次全會精神為主線,以市局基層黨建工作考核細則為落腳點,落實全面從嚴治黨主體
根據會議安排,現將2022年履行抓基層黨建工作職責情況報告如下:一、履職工作特色和亮點1 突出政治建設,著力在思想認識上提高。牢固樹立抓黨建就是抓政績的理念,以“黨建工作抓引領、社區治理求突破,為民服
2022年以來,在**黨委的正確領導下,堅持以習近平新時代中國特色社會主義思想為指導,深入學習宣傳貫徹黨的二十大精神,以黨建工作為統領,扎實開展夯實“三個基本”活動,以“四化四力”行動為抓手,聚力創建
各位領導,同志們:根據會議安排,現就2022年度抓基層黨建工作情況匯報如下:一、主要做法及成效(一)強化政治引領。一是不斷強化理論武裝。堅持通過黨組會、中心組學習會和“三會一課”,第一時間、第一議題學
2022年度抓基層黨建工作述職報告按照黨委工作部署,現將本人2022年度抓基層黨建工作情況報告如下:一、2022年度抓基層黨建工作情況(一)旗幟鮮明講政治將旗幟鮮明講政治放在全局發展首要位置,積極開展
2022年,是我在數計系黨總支書記這個新崗位上度過的第一個完整的工作年度。回首一年來在校黨委的正確領導下,與數計系領導班子和全體師生共同走過的日子,艱辛歷歷在目,收獲溫潤心田。作為黨總支書記,我始終牢
按照考核要求,現將本人一年來,作為統戰部長履行職責、廉潔自律等方面情況報告如下:一、著眼增強政治素質,不斷深化理論學習堅持把旗幟鮮明講政治作為履職從政的第一位要求,帶領統戰系統干部堅決擁護“兩個確立”
**年,緊緊圍繞黨工委、管委會的決策部署,全體人員團結協作、凝心聚力,緊扣黨工委“**”基本工作思路,全力開拓進取,認真履職盡責,圓滿完成各項工作任務。一、個人思想政治狀況檸檬文苑www bgzjy
按照縣委關于開展抓基層黨建述職評議會議的有關要求,經請示縣委組織部同意,今天,我們在此召開2022年度基層黨組織書記抓基層黨建述職評議會議。1 首先,請**黨委書記,**同志述職。**黨委能夠主動研究