哈希表的設計與實現(xiàn)數(shù)據(jù)結構與算法課程設計報告_第1頁
哈希表的設計與實現(xiàn)數(shù)據(jù)結構與算法課程設計報告_第2頁
哈希表的設計與實現(xiàn)數(shù)據(jù)結構與算法課程設計報告_第3頁
哈希表的設計與實現(xiàn)數(shù)據(jù)結構與算法課程設計報告_第4頁
哈希表的設計與實現(xiàn)數(shù)據(jù)結構與算法課程設計報告_第5頁
已閱讀5頁,還剩22頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

1、合肥學院計算機科學與技術系課程設計報告2009 2010 學年第二學期課程 數(shù)據(jù)結構與算法課程設計名稱哈希表的設計與實現(xiàn)學生姓名王東東學號0804012030專業(yè)班級08計本(2)指導教師王昆侖、李貫虹2010 年 5 月課程設計目的“數(shù)據(jù)結構與算法課程設計”是計算機科學與技術專業(yè)學生的集中實踐性環(huán)節(jié)之一,是學習“數(shù)據(jù)結構與算法”理論和實驗課程后進行的一次全面的綜合練習。其目的是要達到理論與實際應用相結合,提高學生組織數(shù)據(jù)及編寫程序的能力,使學生能夠根據(jù)問題要求和數(shù)據(jù)對象的特性,學會數(shù)據(jù)組織的方法,把現(xiàn)實世界中的實際問題在計算機內(nèi)部表示出來并用軟件解決問題,培養(yǎng)良好的程序設計技能。 一、 問題

2、分析和任務定義1、 問題分析 要完成如下要求:設計哈希表實現(xiàn) 號碼查詢系統(tǒng)。實現(xiàn)本程序需要解決以下幾個問題:(1) 如何定義一個包括 號碼、用戶名、地址的節(jié)點。(2) 如何以 號碼和用戶名為關鍵字建立哈希表。(3) 用什么方法解決沖突。(4) 如何查找并顯示給定 號碼的記錄。(5) 如何查找并顯示給定用戶名的記錄。2 任務定義 1、由問題分析知,本設計要求分別以 號碼和用戶名為關鍵字建立哈希表,z在此基礎上實現(xiàn)查找功能。本實驗是要我們分析怎么樣很好的解決散列問題,從而建立一比較合理的哈希表。由于長度無法確定,并且如果采用線性探測法散列算法,刪除結點會引起“信息丟失”的問題。所以采用鏈地址法散列

3、算法。采用鏈地址法,當出現(xiàn)同義詞沖突時,可以使用鏈表結構把同義詞鏈接在一起,即同義詞的存儲地址不是散列表中其他的空地址。 根據(jù)問題分析,我們可以定義有3個域的節(jié)點,這三個域分別為 號碼char num30,姓名char name30,地址char address30。這種類型的每個節(jié)點對應鏈表中的每個節(jié)點,其中 號碼和姓名可分別作關鍵字實現(xiàn)哈希表的創(chuàng)建。 二、 數(shù)據(jù)結構的選擇和概要設計1、數(shù)據(jù)結構的選擇數(shù)據(jù)結構:散列結構。散列結構是使用散列函數(shù)建立數(shù)據(jù)結點關鍵詞與存儲地址之間的對應關系,并提供多種當數(shù)據(jù)結點存儲地址發(fā)生“沖突”時的處理方法而建立的一種數(shù)據(jù)結構。散列結構基本思想,是以所需存儲的結

4、點中的關鍵詞作為自變量,通過某種確定的函數(shù)H(稱作散列函數(shù)或者哈希函數(shù))進行計算,把求出的函數(shù)值作為該結點的存儲地址,并將該結點或結點地址的關鍵字存儲在這個地址中。散列結構法(簡稱散列法)通過在結點的存儲地址和關鍵字之間建立某種確定的函數(shù)關系H,使得每個結點(或關鍵字)都有一個唯一的存儲地址相對應。當需要查找某一指定關鍵詞的結點時,可以很方便地根據(jù)待查關鍵字K計算出對應的“映像”H(K),即結點的存儲地址。從而一次存取便能得到待查結點,不再需要進行若干次的比較運算,而可以通過關鍵詞直接計算出該結點的所在位置。2、概要設計 (1)、哈希表的定義結點的數(shù)據(jù)類型:struct node /定義 姓名

5、 地址 號碼 char name30;char address30; char num30; node * next; ; ElemNode; (2)、哈希地址的計算以姓名為關鍵字的哈希地址計算:從取得的姓名第二個字母開始,取ASCII碼累加,對30求余得所求哈希地址以 號碼為關鍵字的哈希地址計算:從號碼第二位開始,將所有號碼累加之后對30求模得哈希地址 (3)、拉鏈法鏈地址法:在散表結構存放在指針指向的單元中。鏈地址法在解決沖突時,使用鏈表結構把同義詞鏈接在一起,即同義詞的存儲地址不是散列表中其他的空地址。采用C語言定義如下:#define Max_length 100Typedef str

6、uct int key; ElemType data; ElemNode *next;ElemNode;Typedef struct ElemNode *first;ElemHeader,HashTableMax_length;所有的同義詞構成一個單鏈表,再由一個表頭節(jié)點指向這個單鏈表的第一個節(jié)點。這些鏢頭節(jié)點組成一個一維數(shù)組,即散列表。數(shù)組元素的下標對應由散列函數(shù)求出的散列地址。拉鏈法處理沖突的散列表結構and army breeze buy 1boy 2 egg each 5hash 8(4)鏈地址法查找結點的算法思想 a、根據(jù)查找節(jié)點的關鍵字算出哈希地址b、在散列地址所指向的單鏈表中依次

7、尋找節(jié)點 c、如果找到,輸出節(jié)點的信息;否則提示沒有找到三、 詳細設計和編碼 主流程圖。Main ()初始化散列鏈表1并為其動態(tài)分配內(nèi)存空間初始化散列鏈表2并為其動態(tài)分配內(nèi)存空間Menu()主菜單輸入選擇選擇1選9選8查找號碼find_num()mm()查找用戶find2_name)輸出結果輸 出結果選擇2選擇0選擇3選擇4選擇5進行姓名散列l(wèi)ist2()姓名散列結果添加記錄 apend()退出系統(tǒng)return 0進行號碼散列 list()清空creat();creat2()列表已清空號碼散列結果結 束開 始以號碼為關鍵字的Hash()函數(shù)流程圖取整型num2賦給key結束Key=key%20

8、Key=key+(int) numii+i從3開始取numi!=0開 始以姓名為關鍵字的Hash()函數(shù)流程圖取整型name0賦給key2結束Key2=key%20Key2+=nameii+i從0開始取namei不為空 開 始添加結點信息流程圖:利用用戶名為關鍵字插入拉鏈法處理沖突調(diào)用hash()函數(shù)調(diào)用hash()函數(shù)Newname指向newphoneNewphone=input()結束申請新的結點newphone,newname即新的號碼和名字開始申請專利開始 按姓名查找流程圖:q不為空結束輸出無記錄輸出相應記錄q=q-nextq 不為空調(diào)用hash()函數(shù)中新結點q指向phonekey-

9、next開始按號碼查找流程圖:開始調(diào)用hash2()函數(shù)中新結點q指向phonekey-nextq 不為空q=q-nextq不為空輸出無記錄輸出相應記錄結束編碼1、建立節(jié)點struct node /定義 姓名 地址 號碼 char name30;char address30; char num30; node * next; ; typedef node* pnode; /聲明了已有數(shù)據(jù)類型的兩個指針變量typedef node* mingzi; node *phone; node *nam;2、定義哈希函數(shù)這里我們需要定義兩個哈希函數(shù),一個以 號碼為關鍵字,另一個以姓名ASCII之和求模之后

10、的值為關鍵字。主要方法為將 號碼從第二位開始逐一累加并將所得結果對30求模得哈希地址;第二種則是將姓名字符進行強制類型轉換之后得ASCII碼相加對30求模得哈希地址。=求哈希地址源代碼=void hash(char num30) /哈希函數(shù) /將運算的結果所得的余數(shù)作為節(jié)點的存儲地址 int i = 1; key=(int)num0; while(numi!=NULL) key+=(int)numi; i+; key=key%30; void hash2(char name30) /哈希函數(shù) /將運算的結果所得的余數(shù)作為節(jié)點的存儲地址 int i = 1; key2=(int)name0; w

11、hile(namei!=NULL) key2+=(int)namei; i+; key2=key2%30; =(3)、添加節(jié)點接下來就是每個節(jié)點的建立,添加結點,利用鏈地址法解決沖突。建立結點應包括動態(tài)申請內(nèi)存空間。向結點中輸入信息。同時將結點中的next指針等于NULL。添加結點,首先需要利用哈希函數(shù)計算出地址即關鍵字,然后將所得數(shù)據(jù)插入到鏈表中。=動態(tài)申請內(nèi)存空間=void create_phone() /新建節(jié)點 int i; phone=new pnode30; for(i=0;inext=NULL; void create2_num() /新建節(jié)點 int i; nam=new mi

12、ngzi30; for(i=0;inext=NULL; =添加節(jié)點=int apend() /添加節(jié)點 node *newphone; node *newname; newphone=input(); newname=newphone; newphone-next=NULL; newname-next=NULL; hash(newphone-num); /先計算號碼的key hash2(newname-name); /姓名的key2 newphone-next = phonekey-next;/把該key的號碼鏈接到原來的號碼的后一節(jié)點上 phonekey-next=newphone; new

13、name-next = namkey2-next; /把該key的姓名鏈接到原來的號碼的后一節(jié)點上 namkey2-next=newname; return 0; =(4)、查找節(jié)點=void find_num(char num30) /按號碼查找用戶信息 hash(num); node *q=phonekey-next; while(q!= NULL) if(strcmp(num,q-num)=0) break; q=q-next; if(q) coutname_ address_numendl; else cout無此記錄next; while(q!= NULL) if(strcmp(na

14、me,q-name)=0) break; q=q-next; if(q) coutname_ address_numendl; else cout無此記錄endl; =(5)輸出哈希表=void list_num() /以號碼為關鍵字顯示列表 int i; node *p; for(i=0;inext; while(p) coutname_address_numnext; void list2_nam() /以姓名為關鍵字顯示列表 int i; node *p; for(i=0;inext; while(p) coutname_address_numnext; =(6)主函數(shù) main()四、

15、 上機調(diào)試1、在調(diào)試的時候,出現(xiàn)了無法查找姓名或者 號碼相同的用戶的信息 當查找姓名相同或者號碼相同的用戶時,就會出現(xiàn)死循環(huán) 原先代碼如下=部分代碼=while(q!= NULL)if(strcmp(num,q-num)=0)break;q=q-next;if(q)coutname_ address_numendl;else cout無此記錄next; while(q!= NULL) if(strcmp(num,q-num)=0) coutname_ address_numnext; if(flag=0) cout無此記錄endl; =先前出現(xiàn)問題是因為break語句結束語句指能查找一個節(jié)點,

16、改進之后可以實現(xiàn)功能2、文件的操作在這個程序中沒有能成功實現(xiàn),故在最后階段,刪除了這一功能。3、程序中經(jīng)常會出現(xiàn)程序調(diào)試過程中常會出現(xiàn)一些小錯誤,如i,j混淆少括號少分號等小問題都可以按照提示找到,然后改正。測試結果及分析(1)主界面:(2)添加記錄(3)查找記錄a、通過姓名查找姓名不重復的結點b、通過姓名查找姓名重復的結點c、通過 號碼查找結點d、結點不存在結點不存在時,輸出的數(shù)據(jù)為空(4)姓名散列以姓名為關鍵字查找結點,輸出數(shù)據(jù)(5)、號碼散列(6)清空記錄(7)退出系統(tǒng)用戶使用說明添加數(shù)據(jù)不能大于30個數(shù), 號碼為字符型。進入后按照程序界面提示可以進行對數(shù)據(jù)的添加、查找以及按姓名和按 號

17、碼兩種不同方式的散列。本程序在運行時有輔助信息提示,可以十分容易的上手,關鍵信息均通過鍵盤錄入。 參考文獻1 王昆侖,李紅. 數(shù)據(jù)結構與算法. 北京:中國鐵道出版社,2007.2 譚浩強,張基溫. C語言程序設計教程. 3版. 北京:高等教育出版社,2007.八、 附錄#include #include string.husing namespace std; #define NULL 0 unsigned int key; /所需存儲的節(jié)點中的無符號關鍵字作為自變量unsigned int key2; struct node /定義 姓名 地址 號碼 char name30;char add

18、ress30; char num30; node * next; ; typedef node* pnode; /聲明了已有數(shù)據(jù)類型的兩個指針變量typedef node* mingzi; node *phone; node *nam; void hash(char num30) /哈希函數(shù) /將運算的結果所得的余數(shù)作為節(jié)點的存儲地址 int i = 1; key=(int)num0; while(numi!=NULL) key+=(int)numi; i+; key=key%30; void hash2(char name30) /哈希函數(shù) /將運算的結果所得的余數(shù)作為節(jié)點的存儲地址 int

19、 i = 1; key2=(int)name0; while(namei!=NULL) key2+=(int)namei; i+; key2=key2%30; node* input() /輸入節(jié)點 node *one; one = new node; one-next=NULL; cout輸入姓名:one-name; cout輸入地址:one-address; cout輸入 :one-num; return one; int apend() /添加節(jié)點 node *newphone; node *newname; newphone=input(); newname=newphone; new

20、phone-next=NULL; newname-next=NULL; hash(newphone-num); /先計算號碼的key hash2(newname-name); /姓名的key2 newphone-next = phonekey-next;/把該key的號碼鏈接到原來的號碼的后一節(jié)點上 phonekey-next=newphone; newname-next = namkey2-next; /把該key的姓名鏈接到原來的號碼的后一節(jié)點上 namkey2-next=newname; return 0; void create_phone() /新建節(jié)點 int i; phone=n

21、ew pnode30; for(i=0;inext=NULL; void create2_num() /新建節(jié)點 int i; nam=new mingzi30; for(i=0;inext=NULL; void list_num() /以號碼為關鍵字顯示列表 int i; node *p; for(i=0;inext; while(p) coutname_address_numnext; void list2_nam() /以姓名為關鍵字顯示列表 int i; node *p; for(i=0;inext; while(p) coutname_address_numnext; void fi

22、nd_num(char num30) /按號碼查找用戶信息 int flag;hash(num); node *q=phonekey-next; while(q!= NULL) if(strcmp(num,q-num)=0) coutname_ address_numnext; if(flag=0) cout無此記錄next; while(q!= NULL) if(strcmp(name,q-name)=0) coutname_ address_numnext; if(flag=0) cout無此記錄endl; void menu() /菜單 couttt*endl; /cout endl;cout endl;cout endl;couttt 歡迎來到哈希 簿系統(tǒng) endl; cout en

溫馨提示

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

最新文檔

評論

0/150

提交評論