第一篇:軟件工程 通訊錄查詢(xún)系統(tǒng)
《數(shù)據(jù)結(jié)構(gòu)》課程設(shè)計(jì)報(bào)告
計(jì)算機(jī)學(xué)院 軟件工程專(zhuān)業(yè)
題目: 通信錄查詢(xún)系統(tǒng)(查找應(yīng)用)
班級(jí):軟件102班 第11組
組長(zhǎng):
姓名:李偉
學(xué)號(hào):1006550222 組員:
姓名:李呢
學(xué)號(hào):1006550219 姓名:李強(qiáng)
學(xué)號(hào):1006550221
指導(dǎo)老師:xxx
日期:2011 年 12月 30日
程序設(shè)計(jì)書(shū)目錄
一、程序設(shè)計(jì)目標(biāo)
二、問(wèn)題描述
三、需求分析(說(shuō)明課程設(shè)計(jì)的任務(wù))
四、概要設(shè)計(jì)(說(shuō)明課程設(shè)計(jì)中用到的抽象數(shù)據(jù)類(lèi)型的定義、主程序的流程以及各程序模塊之間的調(diào)用關(guān)系等)
五、詳細(xì)設(shè)計(jì)(實(shí)現(xiàn)程序模塊的具體算法)
六、軟件說(shuō)明書(shū)(給出軟件應(yīng)如何使用,使用時(shí)的注意事項(xiàng))
七、源程序清單(要求400行以上,要有注釋說(shuō)明)
八、測(cè)試報(bào)告(調(diào)試過(guò)程中遇到的問(wèn)題及解決方法,并列出測(cè)試結(jié)果,包括輸入和輸出)
九、課程設(shè)計(jì)總結(jié)
一、程序設(shè)計(jì)目標(biāo)
通過(guò)本次課設(shè)進(jìn)一步的了解哈希表函數(shù)及哈希表等有關(guān)概念,2 掌握哈希表查找的過(guò)程及方法。復(fù)習(xí)鞏固大一時(shí)期學(xué)過(guò)的c語(yǔ)言知識(shí)。進(jìn)一步加深對(duì)c語(yǔ)言、數(shù)據(jù)結(jié)構(gòu)、離散數(shù)學(xué)等基礎(chǔ)技能的理解和掌握。
讓我們有一個(gè)既動(dòng)手又動(dòng)腦,獨(dú)立實(shí)踐的機(jī)會(huì),可以讓我們將課本上的理論知識(shí)和實(shí)際郵寄的結(jié)合起來(lái),鍛煉我們的分析解決實(shí)際問(wèn)題的能力。提高我們實(shí)踐編程能力。
通過(guò)本項(xiàng)課程設(shè)計(jì),掌握工程軟件設(shè)計(jì)的基本方法,強(qiáng)化上機(jī)動(dòng)手編程能力,闖過(guò)理論與實(shí)踐相 結(jié)合的難關(guān)!更加了解了c語(yǔ)言的好處和其可用性!同時(shí)增加了同學(xué)之間的團(tuán)隊(duì)合作精神!更加也體會(huì)到以后在工作中團(tuán)隊(duì)合作的重要性和必要性!通過(guò)C語(yǔ)言課程設(shè)計(jì),使學(xué)生了解高級(jí)程序設(shè)計(jì)語(yǔ)言的結(jié)構(gòu),掌握基本的程序設(shè)計(jì)過(guò)程和技巧,掌握基本的分析問(wèn)題和利用計(jì)算機(jī)求解問(wèn)題的能力,具備初步的高級(jí)語(yǔ)言程序設(shè)計(jì)能力。為后續(xù)各門(mén)計(jì)算機(jī)課程的學(xué)習(xí)和畢業(yè)設(shè)計(jì)打下堅(jiān)實(shí)基礎(chǔ)。
二、問(wèn)題描述
設(shè)計(jì)散列表實(shí)現(xiàn)通訊錄查找系統(tǒng)。
(1)設(shè)每個(gè)記錄有下列數(shù)據(jù)項(xiàng):電話(huà)號(hào)碼、用戶(hù)名、地址;
(2)從鍵盤(pán)輸入各記錄,分別以電話(huà)號(hào)碼為關(guān)鍵字建立散列表;
(3)采用二次探測(cè)再散列法解決沖突;(4)查找并顯示給定電話(huà)號(hào)碼的記錄;(5)通訊錄信息文件保存;
(6)要求人機(jī)界面友好,使用圖形化界面;
三、需求分析
一.查詢(xún):用戶(hù)有一個(gè)電話(huà)號(hào)碼,但不知道此電話(huà)號(hào)碼是誰(shuí)的,則需要輸入號(hào)碼來(lái)查詢(xún)?cè)撎?hào)碼是不是此通訊錄中已記錄的人的 號(hào)碼,若是即顯示該號(hào)碼及姓名、所在地,若不是則顯示“無(wú)記錄”。
進(jìn)入主菜單界面,輸入4,進(jìn)入通訊錄查詢(xún)模塊。輸入你想要搜索通訊人的電話(huà)號(hào)碼。屏幕輸出所搜通訊人的先關(guān)信息。二.通訊錄信息添加:
若要向通訊錄中添加新號(hào)碼,也分兩種情況:1若該通訊錄是新的,既沒(méi)有任何通訊記錄的,則直接往里添加,需先輸入姓名,隨即輸入號(hào)碼和所在地,用于存儲(chǔ)。2若通訊錄不是空的,再添加新號(hào)碼時(shí)則需在最后一個(gè)號(hào)碼后面進(jìn)行添加(輸入姓名、電話(huà)號(hào)碼及所在地),以此類(lèi)推。
進(jìn)入主菜單,輸入1,進(jìn)入通訊錄信息添加模塊。按照要求依次輸入姓名、電話(huà)號(hào)碼、住址。三.通訊錄信息刪除:
若要對(duì)通訊錄中的內(nèi)容進(jìn)行刪除: 然后輸入所要?jiǎng)h除的號(hào)碼進(jìn)行刪除
刪除成功。出現(xiàn)提示信息。按任意鍵回到主菜單。
四、概要設(shè)計(jì)
對(duì)功能鍵相對(duì)應(yīng)的函數(shù)分別對(duì)各個(gè)函數(shù)在程序中進(jìn)行定義如下:
void Menu()void Create()void Append()void CreateHash()void Find()void Delete()void Alter()void List()void Save()
void Load()
然后根據(jù)各功能鍵的選擇主函數(shù)分別調(diào)用功能鍵相對(duì)應(yīng) 4 的函數(shù)來(lái)實(shí)現(xiàn)通訊錄的查詢(xún)系統(tǒng)。
五、詳細(xì)設(shè)計(jì)
1、定義結(jié)構(gòu)體變量
typedef struct people //記錄 { NA name;NA tel;//關(guān)鍵字
NA add;}Record;//查找表中記錄類(lèi)型
typedef struct //建立哈希表 { Record *elem[HASHSIZE];//數(shù)據(jù)元素存儲(chǔ)基址 int count;//當(dāng)前數(shù)據(jù)元素個(gè)數(shù) int size;//當(dāng)前容量 }HashTable;
2、定義顯示函數(shù) void Menu()
3、定義建立時(shí)間的函數(shù) void benGetTime()
4、定義創(chuàng)建新的通訊錄并添加信息的函數(shù)
void Create(Record* a)
5、定義關(guān)鍵字比較函數(shù)
Status eq(NA x,NA y)
6、定義添加信息函數(shù)
void Append(Record* a)
7、定義顯示通訊錄中所有信息函數(shù)
void List(Record* a)
8、定義哈希函數(shù)
int Hash(NA str)
9、定義沖突處理函數(shù)
Status collision(int p,int &c)
10、定義建立散列表的函數(shù)
void CreateHash(HashTable* H,Record* a)
11、定義通訊錄查找的函數(shù)
void Find(HashTable* H,int &c)
12、定義修改信息的函數(shù)
void Alter(HashTable* H,int &c)
13、定義刪除信息的函數(shù)
void Delete(HashTable* H,int &c)
14、定義保存信息到指定文件的函數(shù)
void Save(HashTable* H)
15、定義從指定文件中讀取信息的函數(shù)
void Load()
16、定義主函數(shù)
int main(int argc, char* argv[]){ system(“color FO”);system(“CLS”);int c,flag=1;HashTable *H;H=(HashTable*)malloc(LEN);for(int i=0;i
case 0:Quit();return 0;break;case 10:;;break;default: printf(“你輸錯(cuò)了,請(qǐng)重新輸入!”);printf(“n”);}
system(“CLS”);} return 0;}
六、軟件說(shuō)明書(shū)
雙擊程序,程序運(yùn)行后,進(jìn)入通信錄查詢(xún)系統(tǒng)菜單的操作界面,然后采用鍵盤(pán)進(jìn)行操作。各功能鍵的選擇如下:
1、創(chuàng)建新的通訊錄并寫(xiě)入新的信息
2、添加某人的信息
3、以電話(huà)號(hào)碼建立散列表
4、查找并顯示給定電話(huà)號(hào)碼的記錄
5、刪除某人的信息
6、修改某人的信息
7、顯示通訊錄中所有記錄
8、保存通訊錄所有記錄到指定文件
9、從指定文件中讀取通訊錄中的記錄 0、退出選單
選擇1,建立新的通訊錄,通訊錄創(chuàng)建成功,按Enter鍵進(jìn)入添加信息界面,界面會(huì)出現(xiàn)
根據(jù)系統(tǒng)提示進(jìn)行相應(yīng)的添寫(xiě),添加成功之后,按Enter鍵返回主菜單。
選擇2,在通訊錄的末尾寫(xiě)入新的信息,與上訴添加信息操作相同。同樣按Enter鍵返回主菜單。
選擇3,會(huì)立即調(diào)用沖突處理函數(shù)以及建立散列表,界面上會(huì)顯示沖突次數(shù),哈希表容量和當(dāng)前儲(chǔ)存記錄的個(gè)數(shù),按Enter鍵返回主菜單。3功能鍵必須在4、5、6功能鍵之前選擇,才能使4、5、6功能鍵派上用場(chǎng)。
選擇4,查找某人信息,寫(xiě)入查找的電話(huà)號(hào)碼,如果通訊錄中有則會(huì)出現(xiàn)查找成功否則出現(xiàn)此人不存在,查找不成功。按Enter鍵返回主菜單。
選擇5,刪除某人信息,寫(xiě)入刪除的電話(huà)號(hào)碼,如果通訊錄中有則會(huì)出現(xiàn)刪除成功否則出現(xiàn)此人不存在,刪除不成功。按Enter鍵返回主菜單。
選擇6,修改某人信息,寫(xiě)入修改的電話(huà)號(hào)碼,通過(guò)查找函數(shù)找到要修改的信息,在對(duì)找的的信息進(jìn)行修改,如果通訊錄中 有則會(huì)出現(xiàn)原信息讓用戶(hù)輸入修改后的信息,根據(jù)系統(tǒng)的提示輸入修改后的信息,按Enter鍵會(huì)出現(xiàn)修改成功,否則出現(xiàn)此人不存在,修改不成功。按Enter鍵返回主菜單。
選擇7,界面會(huì)輸出全部成員的信息。按Enter鍵返回主菜單。選擇8,利用存盤(pán)函數(shù)保存數(shù)據(jù)到指定文件,界面會(huì)出現(xiàn)保存成功,按Enter鍵返回主菜單。
選擇9,載入存儲(chǔ)過(guò)的電話(huà)、姓名、地址,界面會(huì)出現(xiàn)指定文件所存儲(chǔ)的所有信息。按Enter鍵返回主菜單。選擇0,顯示再見(jiàn),按Enter鍵退出系統(tǒng)。
七、源程序清單
#include
typedef struct people //記錄 { NA name;NA tel;//關(guān)鍵字 NA add;}Record;//查找表中記錄類(lèi)型
typedef struct //建立哈希表
{ Record *elem[HASHSIZE];//數(shù)據(jù)元素存儲(chǔ)基址 int count;//當(dāng)前數(shù)據(jù)元素個(gè)數(shù) int size;//當(dāng)前容量 }HashTable;int i;void Menu(){ printf(“
n”);printf(“ ## ttt ―――――― ttt ##n”);printf(“
# ttt
丨
1.創(chuàng)建
丨 # n”);printf(“
# ttt
―――――― #n”);printf(“
# ttt
丨
2.寫(xiě)入
丨 #n”);printf(“
# ttt
―――――― #n”);printf(“
# ttt
丨
3.建表
丨 #n”);printf(“
# ttt
―――――― #n”);printf(“
# ttt
丨
4.查找
丨 #n”);printf(“
# ttt
―――――― #n”);printf(“
# ttt
丨
5.刪除
丨 #n”);printf(“
# ttt
―――――― #n”);printf(“
# ttt
丨
6.修改
丨 #n”);printf(“
# ttt
―――――― #n”);printf(“
# ttt
丨
7.查看
丨 #n”);printf(“
# ttt
―――――― #n”);printf(“
# ttt
丨
8.保存
丨
#n”);printf(“
# ttt
―――――― #n”);printf(“
# ttt
丨
9.讀取
丨 #n”);printf(“
# ttt
―――――― #n”);printf(“
# ttt
丨
0.退出
丨 #n”);printf(“
## ttt
―――――― ##n”);printf(“
n”);}
void benGetTime()//建立時(shí)間函數(shù) { SYSTEMTIME sys;GetLocalTime(&sys);printf(“%4d/%02d/%02d %02d:%02d:%02d.%03d n”,sys.wYear,sys.wMonth,sys.wDay,sys.wHour,sys.wMinute, sys.wSecond,sys.wMilliseconds);}
Status NUM_BER;//記錄的個(gè)數(shù) Status NUM_BER1;
void Create(Record* a)//創(chuàng)建新的通訊錄 { system(“CLS”);//調(diào)用DOS命令CLS能夠清屏
FILE *fp1,*fp2;if((fp1=fopen(“record.txt”,“r”))!=NULL)//打開(kāi)文件
{ fclose(fp1);//關(guān)閉文件
} else {
fp2=fopen(“record.txt”,“w”);//如果不存在record.txt就創(chuàng)建一個(gè)
fclose(fp2);11 }
printf(“n”);
printf(“
#####n”);printf(“==================== → 創(chuàng)建成功 ← ===================n”);
printf(“
#####n”);
printf(“n”);printf(“◇◆請(qǐng)按ENTER進(jìn)入添加通訊信息菜單◇◆n”);getchar();system(“CLS”);system(“CLS”);//調(diào)用DOS命令CLS能夠清屏
printf(“
#####n”);printf(“==================== → 用戶(hù)信息記錄表 ← ===================n”);
printf(“
#####n”);printf(“輸入要添加的個(gè)數(shù):n”);scanf(“%d”,&NUM_BER);for(i=0;i { printf(“請(qǐng)輸入第%d個(gè)記錄的用戶(hù)名:n”,i+1);scanf(“%s”,a[i].name);printf(“請(qǐng)輸入%d個(gè)記錄的電話(huà)號(hào)碼:n”,i+1);scanf(“%s”,a[i].tel);printf(“請(qǐng)輸入第%d個(gè)記錄的地址:n”,i+1);scanf(“%s”,a[i].add); } getchar(); printf(“ #n”); printf(“添加成功!!n”); benGetTime();printf(“~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~n”);printf(“◇◆請(qǐng)按ENTER返回功能操作菜單◇◆n”);printf(“ #n”);12 getchar();} Status eq(NA x,NA y)//關(guān)鍵字比較,相等返回SUCCESS;否則返回UNSUCCESS { if(strcmp(x,y)==0){ return SUCCESS;} else return UNSUCCESS;} void Append(Record* a)//鍵盤(pán)輸入各人的信息 { system(“CLS”);//調(diào)用DOS命令CLS能夠清屏 printf(“ #####n”);printf(“==================== → 用戶(hù)信息記錄表 ← ===================n”); printf(“ #####n”);printf(“輸入要添加的個(gè)數(shù):n”);scanf(“%d”,&NUM_BER1);int j=i;for(i;i printf(“ #n”); printf(“添加成功!!n”); benGetTime();13 printf(“~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~n”);printf(“◇◆請(qǐng)按ENTER返回功能操作菜單◇◆n”);printf(“ #n”);getchar();} void List(Record* a)//顯示通訊錄中所有記錄 { Record *p;p=a;int i;system(“CLS”);//調(diào)用DOS命令CLS能夠清屏 printf(“ #####n”);printf(“==================== → 用戶(hù)信息記錄表 ← ===================n”); printf(“ #####n”);if(a!=NULL){ printf(“nn姓名t電話(huà)號(hào)tt地址n”); printf(“_____________________________________________________n”);for(i=0;i { printf(“%st%stt%sn”,a[i].name,a[i].tel,a[i].add); printf(“_____________________________________________________n”); } } else { printf(“對(duì)不起!沒(méi)有任何聯(lián)系人記錄!nn”); printf(“===============n”);} benGetTime();printf(“ #####n”);14 printf(“◇◆請(qǐng)按ENTER返回功能操作菜單◇◆n”);printf(“ #####n”);getchar();} int Hash(NA str)//哈希函數(shù) { system(“CLS”);//調(diào)用DOS命令CLS能夠清屏 long n;int m;n = atoi(str);//整型數(shù).m=n%HASHSIZE;//造哈希函數(shù) return m;//} Status collision(int p,int &c)//用二次探測(cè)再散列法解決沖突 { int i,q;i=c/2+1;while(i { return q; } else { i=c/2+1; } } else { q=(p-i*i)%HASHSIZE;把字符串轉(zhuǎn)換成用除留余數(shù)法構(gòu)并返回模值 沖突處理函數(shù),采15 c++;if(q>=0) { return q; } else { i=c/2+1; } } } return UNSUCCESS;} void CreateHash(HashTable* H,Record* a)//建表,以電話(huà)號(hào)碼為關(guān)鍵字,建立相應(yīng)的散列表 { system(“CLS”);//調(diào)用DOS命令CLS能夠清屏 int i,p=-1,c,pp;for(i=0;i { pp=collision(p,c);//若哈希地址沖突,進(jìn)行沖突處理 if(pp<0) { printf(“ #####n”);printf(“==================== → 用戶(hù)信息記錄表 ← ===================n”); printf(“ #####n”);printf(“第%d記錄無(wú)法解決沖突”,i+1);//需要顯示沖突次數(shù)時(shí)輸出 continue; } //無(wú)法解決沖突,跳入下一循環(huán) } H->elem[pp]=&(a[i]);//求得哈希地址,將信息存入 H->count++; printf(“ #####n”);printf(“==================== → 用戶(hù)信息記錄表 ← ===================n”); printf(“ #####n”);printf(“第%d個(gè)記錄沖突次數(shù)為%d。n”,i+1,c);//需要顯示沖突次數(shù)時(shí)輸出 } printf(“n建表完成!n此哈希表容量為%d,當(dāng)前表內(nèi)存儲(chǔ)的記錄個(gè)數(shù)為%d.n”,HASHSIZE,H->count);benGetTime();printf(“ #####n”);printf(“◇◆請(qǐng)按ENTER返回功能操作菜單◇◆n”);printf(“ #####n”);getchar();} void Find(HashTable* H,int &c)//在通訊錄里查找電話(huà)號(hào)碼關(guān)鍵字,若查找成功,顯示信息 { system(“CLS”);//調(diào)用DOS命令CLS能夠清屏 printf(“ #####n”);printf(“==================== → 用戶(hù)信息記錄表 ← ===================n”); printf(“ #####n”);benGetTime();17 NA tele;printf(“n請(qǐng)輸入要查找記錄的電話(huà)號(hào)碼:n”);scanf(“%s”,tele);int p,pp;p=Hash(tele);pp=p;while((H->elem[pp]!=NULL)&&(eq(tele,H->elem[pp]->tel)==-1))pp=collision(p,c);if(H->elem[pp]!=NULL&&eq(tele,H->elem[pp]->tel)==1){ printf(“ #####n”);printf(“==================== → 用戶(hù)信息記錄表 ← ===================n”); printf(“ #####n”);printf(“n查找成功!n查找過(guò)程沖突次數(shù)為%d.以下是您需要要查找的信息:nn”,c);// printf(“姓 名:%sn電話(huà)號(hào)碼:%sn聯(lián)系地址:%sn”,H->elem[pp]->name,H->elem[pp]->tel,H->elem[pp]->add); printf(“nn姓名t電話(huà)號(hào)tt地址n”); printf(“_____________________________________________________n”); printf(“%st%stt%sn”,H->elem[pp]->name,H->elem[pp]->tel,H->elem[pp]->add); printf(“_____________________________________________________n”);} else printf(“n此人不存在,查找不成功!n”);benGetTime();getchar();printf(“ #####n”);printf(“◇◆請(qǐng)按ENTER返回功能操作菜單◇◆n”);printf(“ #####n”);getchar();} void Alter(HashTable* H,int &c)//在通訊錄里修改某人信息 { system(“CLS”);//調(diào)用DOS命令CLS能夠清屏 printf(“ #####n”);printf(“==================== → 用戶(hù)信息記錄表 ← ===================n”); printf(“ #####n”);benGetTime();NA tele;printf(“n請(qǐng)輸入要修改記錄的電話(huà)號(hào)碼:n”);scanf(“%s”,tele);int p,pp;p=Hash(tele);pp=p;while((H->elem[pp]!=NULL)&&(eq(tele,H->elem[pp]->tel)==-1))pp=collision(p,c);if(H->elem[pp]!=NULL&&eq(tele,H->elem[pp]->tel)==1){ printf(“ #####n”);printf(“==================== → 用戶(hù)信息記錄表 ← ===================n”); printf(“ #####n”); printf(“n以下是您需要修改的信息:”); printf(“n”); printf(“nn姓名t電話(huà)號(hào)tt地址n”); printf(“_____________________________________________________n”); printf(“%st%stt%sn”,H->elem[pp]->name,H->elem[pp]->tel,H->elem[pp]->add); printf(“_____________________________________________________n”); (H->elem)[pp]->tel[0]='