JAVA散列表个人通讯录_散列表实现简易通讯录
散列表實現通訊錄
1、項目研究背景與意義
背景:隨著信息活動在國民經濟中主導地位的確立和信息產業的崛起,信息資源管理作為一個專有名詞和獨立的學科逐漸發展起來。如何積極開發、合理配置和有效利用信息資源,日益成為社會中急需解決的問題。由于計算機和通信技術的高速發展,推廣應用計算機進行信息管理成為推動信息化工作的重要內容,信息管理系統正是應用計算機信息化過程中出現的新事物。它能夠提供信息、支持企業和組織的運行,對管理者作出決策有重要的意義。信息管理系統用于管理中可以大大減輕管理人員的工作負擔,提高工作效率。使管理更加程序化,科學化。
對一個組織而言,內部管理的好壞直接關系到組織的存在與良好運行,而內部管理中非常重要的一項就是對他人的連續聯系,他人的具體情況,如:手機號、姓名、家庭住址......;一旦工作人員沒有及時出現在自己崗位時或因其它情況發生變化時,可以迅速連續或找到本人及其家人了解情況。本系統是針對通信錄管理系統編寫的。對于許多人來說,已經認識到一個好的通信錄是很必要的,可以方便和其他人的聯系;但是應用計算機來進行管理還無法實現,所以就需要專門的管理軟件來幫助實現。、
隨著科技的進步和信息產業的飛速發展,通訊錄成為了現代生活中一個重要的工具。本通訊錄管理系統利用計算機對通信錄進行統一管理,包括添加、修改、查詢等功能,實現通信錄管理工作的系統化、規范化和自動化,為人們的工作和生活提供便利。整個系統程序采用C語言實現,C語言是目前國際上比較流行的計算機高級編程語言之一,因其簡潔、使用方便且具備強大的功能而受到編程人員的普通青睞。它既適合作為系統描述語言,也可用來編寫系統軟件,還可用來編寫應用軟件。
意義:計算機已經成為我們學習和工作的得力助手,使用其可方便的管理通訊錄。目前,大多數人的通訊管理水平還停留在紙介質的基礎上,這樣的機制已經不能適應時代的發展了,他浪費了大量的人力物力,在信息時代這種傳統的管理方法必然被計算機為基礎的信息管理所取代。
開發這一系統的好處大約有以下幾點:
第一、可以安全、高效的存儲大量的通訊錄信息;
第二、只需一檔案錄入即可完成操作系統,節省人力;
第三、可以迅速的查到所需的通訊錄信息。
2、系統需求分析
根據用戶需求,通訊錄需要長期保存聯系人信息,且用戶可實現對聯系人的添加、刪除、修改和查找等功能。
首先,需要創建通訊錄。
Create?(?)的功能:創建新的通訊錄。
為長期保存聯系人,需要以文件形式存儲,并且可以隨時對文件中的信息進行讀取。
本系統應完成以下幾方面的功能:
Load?(?)的功能:從指定文件中讀取通訊錄中的記錄。
Save?(?)的功能:保存通訊錄中的所有記錄到指定文件中。
當通訊錄中信息為空,需要首先對通訊錄進行初始化。
Start?(?)的功能:初始化通訊錄。
需要添加、刪除、修改、查找聯系人時,可以隨時進行增、刪、改、查等功能。
newnumz(?)的功能:在通訊錄寫入新的信息,并返回選單。
Findnum?(?)的功能:查詢某人的信息,如果找到了,則顯示該人的信息,如果沒有則提示通訊錄中沒有此人的信息,并返回選單。
Alter?(?)的功能:修改某人的信息,如果未找到要修改的人,則提示通訊錄中沒有此人的信息,?并返回選單。
Delete?(?)的功能:刪除某人的信息,如果未找到要刪除的人,則提示通訊錄中沒有此人的信息并返回選單。
根據用戶的需求,有時需要顯示通訊錄中的全部聯系人信息。
List?(?)的功能:顯示通訊錄中的所有記錄。
3、概要設計
4、詳細設計
4.1結構體設計
個人信息以結構體實現,包括電話號碼、姓名和地址。
struct?xinxi
{
int?num;
char?name[10];
char?address[10];
};//個人信息結構體
散列表以順序表實現,可以存儲50個聯系人的信息。
struct?hash
{
int?max;
int?len;
Data?h[50];
};//散列表
4.2創建散列表Create()
創建散列表Create(),為散列表申請空間,并把所有號碼置為0.
phash?creat(){
int?i;
phash?p=(phash)malloc(sizeof(struct?hash));
if(p!=NULL){
p->max=50;
p->len=0;
for(i=0;i<50;i++)?{p->h[i].num=0;}?//關鍵碼全部置零
return?p;
}
}
4.3檢索函數Find()
檢索函數Find(),檢索電話號碼在散列表中是否存在。若存在,則通過position返回地址,并返回1;若不存在,返回0.
int?find(phash?p,int?num,int?*position){
int?d,inc;
d=num%50;//散列函數
for(inc=0;inc<50;inc++){
if(p->h[d].num==num){
*position=d;//檢索成功
return?1;
}
else?if(p->h[d].num==0){
*position=d;//檢索失敗
return?0;
}
d=(d+1)%50;
}
*position=-1;//散列表溢出
return?0;
}
4.4插入函數Append()
插入函數Append(),若所要插入的聯系人的號碼已存在,則輸出聯系人已存在;否則將聯系人信息插入到應在位置。
int?Append(phash?p,Data?x){
int?position;
if(find(p,x.num,&position)==1)//散列表中已經存在
{
printf("發現已經存在!\n");
}
else?if(position!=-1){
p->h[position]=x;//插入信息
p->len++;
}
else?return?0;
return?1;
}
4.5初始化函數start()
初始化函數start(),循環寫入聯系人信息保存至臨時結構體st,并調用插入函數Append(),將信息插入到散列表中。
int?start(phash?p){
int?i;
Data?st;
printf("請輸入三名聯系人的信息!(電話號碼,姓名,地址,空格隔開)\n");
for(i=0;i<3;i++)
{
scanf("%d?%s?%s",&st.num,&st.name,&st.address);
Append(p,st);
}
return?1;
}
4.6查找聯系人函數Findnum()
查找聯系人函數Findnum(),輸入聯系人號碼通過調用Find()函數來檢索該聯系人信息是否存在。若存在則輸出聯系人信息;若不存在,則輸出所查找聯系人不存在。
int?findnum(phash?p){
int?i,num,position;
printf("輸入要查詢的聯系人的號碼!\n");
scanf("%d",&num);
if(find(p,num,&position)==1)
{
printf("%d\t%s\t%s\n",num,p->h[position].name,p->h[position].address);
}
else?printf("要查找的聯系人不存在\n");
return?1;
}
4.7添加聯系人函數newnum()
添加聯系人函數newnum(),輸入要插入的聯系人信息,通過調用插入函數Append(),若聯系人已存在,則輸出聯系人存在提示;若不存在,則將聯系人信息添加到通訊錄。
int?newnum(phash?p){
int?num,position;
Data?n;
printf("輸入要新建的聯系人的號碼!\n");
scanf("%d",&num);
if(find(p,num,&position)==1)//檢索聯系人是否存在
{printf("聯系人存在!\n");
return?0;
}
else{
n.num=num;
printf("請輸入需要新建聯系人的信息!(姓名?地址,空格隔開)\n");
scanf("%s?%s",&n.name,&n.address);
Append(p,n);
printf("新建聯系人完成!\n");
return?1;
}
}
4.8刪除函數Delete()
刪除函數Delete(),刪除一個元素后會產生空位,因為有可能因碰撞導致其余聯系人不再以散列表形式存儲,需逐項查找空位后面的元素把所碰撞元素賦值到空位,如此循環下去,直到構成一個新的散列表。通過調用檢索函數find()返回刪除元素所在位置position,記為i,刪除該元素后用j標記空位,用(i++)%50來查找空位后元素,用r來表示i標記位置的元素未發生碰撞時應在的位置。在for循環中通過使用3個if語句來排除不受影響的元素,而后將選出的元素賦值到相應位置。
int?Delete(phash?p){
int?num,i,j,r;//num:要刪除的聯系人號碼;j:標記空位;i:移動查找是否碰撞;r:i的聯系人號碼未發生碰撞時應在位置。
int?position;
printf("輸入要刪除的聯系人的號碼!\n");
scanf("%d",&num);
if(find(p,num,&position)==1){
i=position;
for(;;){
p->h[i].num=0;//刪除i產生一個空位。
j=i;//j存放空位位置,從后面的元素中選出一個元素填補空位
for(;;){
i=(++i)%50;
if(p->h[i].num==0)//若遇到未使用的位置則調整結束
{
printf("聯系人已經刪除!\n");
return?1;
}
r=p->h[i].num%50;//r為i位置中的元素未發生碰撞應在位置
///
//若r位于空位和當前位置i之間,則說明該元素不受影響,則跳出尋找下一個
if(j
continue;
if(j>i?&&?j
continue;
if(j>i?&&?r<=i)
continue;
//以上3條語句保證了r位于i與j之間
break;
}
p->h[j]=p->h[i];//將選擇的元素賦值到空位
}
}
else?{printf("不存在該人!\n");}
return?1;
}
4.9修改聯系人函數alter()
修改聯系人函數alter(),輸入聯系人號碼通過調用find()函數來檢索,若該聯系人信息存在,則將更新后的信息保存至通訊錄;若不存在,則輸出不存在該人。
int?alter(phash?p){
int?num;
int?position;
printf("輸入要修改的聯系人的號碼!\n");
scanf("%d",&num);
if(find(p,num,&position)==1){//檢索是否存在該聯系人
p->h[position].num=num;
printf("請輸入需要修改的信息!(姓名?地址,空格隔開)\n");
scanf("%s?%s",&p->h[position].name,&p->h[position].address);
}
else
{
printf("不存在該人!\n");
}
return?1;
}
4.10顯示函數list()
顯示函數list(),將散列表中的所有聯系人信息全部輸出到界面。
int?list(phash?p){
int?i;
for(i=0;i<50;i++){
if(p->h[i].num!=0)
printf("%d\t%s\t%s\n",p->h[i].num,p->h[i].name,p->h[i].address);
}
return?1;
}
4.11保存文件函數save()
保存文件函數save(),當文件已存在時,格式化輸出散列表中的聯系人信息到指定文件“xinxi.txt”。當文件不存在時,自動創建新文件“xinxi.txt”并格式化輸出。
int?save(phash?p){
int?i;
FILE?*fout;
if((fout=fopen("xinxi.txt","w"))==NULL)//判斷文件是否存在
{
printf("寫入文件失敗!\n");
return?0;
}
for(i=0;i<50;i++)
{???if(p->h[i].num?!=?0)//判斷聯系人是否存在
fprintf(fout,"%d?%s?%s\n",p->h[i].num,p->h[i].name,p->h[i].address);//輸出存在的聯系人
}
fclose(fout);//關閉文件
printf("文件已保存\n");
return?1;
}
4.12讀取函數load()
讀取函數load()當文件存在時并且未到達文件末尾,循環讀取聯系人信息到臨時存儲區temp,然后調用插入函數Append(),把聯系人信息插入到散列表。
int?load(phash?p){
FILE?*fin;
Data?temp;
int?i;
if((fin=fopen("xinxi.txt","r"))==NULL)//判斷文件是否存在
{
printf("文件讀取失敗!\n");
return?0;
}
while(!feof(fin))//判斷文件是否結束
{
i=fscanf(fin,"%d?%s?%s",&temp.num,&temp.name,&temp.address);//讀取聯系人信息
if(i==-1)?break;
else?Append(p,temp);//把讀取的信息插入散列表
}
fclose(fin);
printf("文件讀取成功\n");
return?1;
}
5、調試分析
開始界面:
試驗初始化功能:
試驗保存文件功能:
試驗讀取功能:
試驗顯示功能:
試驗新建功能:
試驗查詢功能:
試驗查詢異常數據:
試驗刪除功能:
試驗刪除功能結果是否正確:
試驗刪除異常數據:
試驗修改異常數據:
試驗修改功能:
試驗修改功能結果是否正確:
6.問題及難點所在
創建函數的難點:為散列表申請空間后,所有位置均為空值,由于在檢索函數及插入函數中都要對散列表中每個位置的元素及要操作的元素進行比較,當位置為空比較時會生成亂碼,干擾下一步的操作。
改進方法是:將所有位置均賦值為0.
檢索函數的難點:在查找、新建、刪除等功能中所要操作元素及其對散列表中對應位置是否為空及散列表是否溢出等情況均未知。無法進行下一步操作。
改進方法:定義檢索函數根據用戶的號碼進行散列檢索,用散列函數來逐項查找位置,若當前位置已存在或為空時,返回當前位置;若散列表以溢出,則將當前位置賦值為-1.
添加聯系人信息是個難點,要先輸入要添加的聯系人號碼,調用Find()函數來檢索該聯系人在散列表中是否已經存在,若存在,輸出“聯系人存在”,結束該程序,若不存在,將添加聯系人呢相關信息保存到結構體內,通過調用插入函數Append()添加聯系人信息。
保存和讀取函數是一個難點:在保存文件函數中,使用fopen函數打開文件,對散列表進行遍歷,當表中有元素時,使用fprintf()函數,格式化輸出到“xinxi.txt”文件,然后用fclose()函數關閉文件。在讀取文件時,使用fopen()函數打開文件,當文件未到達末尾,就格式化讀取信息到臨時結構體,然后調用插入函數Append(),把信息存放到散列表中,最后用fclose()函數關閉文件。
刪除函數是一個難點:不能簡單的將要刪除的結點的電話號碼直接置為0,因為為0是檢索失敗的根據,這樣直接置0,會導致碰撞的元素檢索失敗。
解決方法:1:在被刪除結點做標記(例如將關鍵碼改為負值),不是真的刪除,這樣,做了多次刪除后,形式上散列表是滿的,但實際上是很空的。
2:繞過刪除操作。把要刪除號碼置為0,然后保存文件,重新創建散列表,讀取文件,這樣新建了一個散列表,從而繞過了刪除的麻煩討論。
3:直接刪除元素,產生空位,通過移動元素,使碰撞關系仍然成立。這也是我們采用的方法。我們通過輸入聯系人號碼調用find()函數進行檢索,若該聯系人存在,將該聯系人的信息刪除并返回當前位置賦值給i,后用j=i標記當前空位置,用i++繼續向下查找,用r表示i聯系人號碼未發生碰撞應在位置。用3個if語句依次排除不受影響的元素,當r位于j與i之間時,所標記的元素即為不需要調整的元素。后用for循環繼續查找,直到出現未使用的位置。
7、算法設計的思想
整體思想:
為了方便的實現快速查找,算法中用到了數據結構中“字典的散列表示”這一章節的知識,基本思想是:選擇一個從關鍵碼到地址的散列函數h,對于每個關鍵碼為key的元素,計算出h(key),期望把對應的元素存儲到h(key)指示的地址上,如果兩個不相等的關鍵碼key1和key2,用散列函數h計算得到相同的散列地址(即h(key1)=h(key2)),此現象即為碰撞,為了實現散列法必須解決存儲時碰撞的問題,處理碰撞需要付出時間和空間代價,因此要提高散列法處理效率,就應該盡量減少碰撞。算法中對于碰撞的處理使用的是線性探查法,即將基本存儲區看作一個循環表。若在地址為d=h(key)的單元發生碰撞,則依次探查下述地址單元:d+1,d+2,....,m-1,0,1,....d-1(m為基本存儲區的長度)直到找到一個空單元或查找到關鍵碼為key的元素為止。如果從單元d開始探查,查找一遍后,又回到地址d,則表示基本存儲區已經溢出。
本算法中采用的散列函數為h(key)=key%50.
7.1?結構體設計
需要包括聯系人的電話號碼,姓名和住址。
7.2創建散列表create()
創建函數的思想:由于散列表創建后要方便用戶檢索及各項操作,所以在創建之后將所有的空位置全部賦值為0以方便下一步的操作。
7.3檢索函數find()
檢索函數的思想:在新建、查找、刪除等功能中所操作元素當前位置是否為空以及為空時操作對象的位置等未知,所要定義檢索函數來實現此功能。我們設計通過輸入用戶號碼num來進行散列檢索,用(num)%50來查找應在位置,若查找成功,則返回1,否則若所在位置號碼為空,則返回0,并將當前元素位置賦值給d;若既不為1,也不為0,繼續對下一個位置進行查找。
7.4插入函數Append()
插入函數的思想:由于所要插入元素應在位置是否為空未知,所以調用檢索函數來判斷,若已存在,則返回;否則將元素插入到該位置。
7.5初始化函數start()
初始化函數的思想:定義結構體st來臨時存儲信息,后調用插入函數Append()來將所有信息插入到規定位置。
7.6查找聯系人函數findnum()
為查找到聯系人的相關信息,輸入要查詢的聯系人的號碼,通過調用Find()函數來檢索該聯系人信息是否存在。若存在,則輸出聯系人信息;若不存在,則輸出所查找聯系人不存在。
7.7添加聯系人函數newnum()
為添加聯系人信息,先輸入要添加的聯系人號碼,調用Find()函數來檢索該聯系人在散列表中是否已經存在,若存在,輸出“聯系人存在”,結束該程序,若不存在,將添加聯系人呢相關信息保存到結構體內,通過調用插入函數Append()添加聯系人信息。
7.8刪除函數Delete()
我們通過輸入聯系人號碼調用find()函數進行檢索,若該聯系人存在,將該聯系人的信息刪除并返回當前位置賦值給i,后用j=i標記當前空位置,用i++繼續向下查找,用r表示i聯系人號碼未發生碰撞應在位置。用3個if語句依次排除不受影響的元素,當r位于j與i之間時,所標記的元素即為不需要調整的元素。后用for循環繼續查找,直到出現未使用的位置。
7.9修改函數alter()
為修改聯系人信息,先輸入要修改的聯系人號碼,通過調用find()函數來檢索該聯系人在散列表中是否已經存在,若該聯系人存在,請輸入需要修改的信息保存至通訊錄;若不存在,則輸出“不存在該人”。
7.10顯示函數list()
設置循環,從散列表中的第一個位置依次向后檢索,若所檢索位置非空,將散列表中信息輸出。
6、算法流程圖
9:總結
由于時間緊迫和個人能力的不足,所做的程序還有極大的改善空間,只能算是勉強達到要求罷了。例如存儲的電話號碼僅有五位,這在實際使用中是遠遠不夠的,還有如果不按照要求輸入信息,可能產生未知錯誤,程序的健壯性不夠。
此次課程設計,感觸很多,雖然在做程序的時候由于基礎知識掌握不牢,吃了很多苦頭,但是總體來說還是甜多于苦,讓我知道了我離實際應用的差距。在一次次的修改與檢查中,鞏固了我許多知識,讓我明白了只有理論與實踐結合,才能更好的掌握知識,才能真正的做出合格的產品。
本次課程設計,讓我進一步明白了應用程序是怎么產生的,從需求分析到詳細設計,只有清晰的結構,才能產生合格的程序,課程設計把我以前學到的知識第一次結合起來,使我第一次感覺到編程不只是精細的繡花,更是縱觀全局,運籌帷幄的戰爭,只有大的方向和結構清楚,才能打贏這場戰爭。
本次課程設計,極大的提升了我的實際動手能力和獨立思考能力。在刪除函數的設計過程中,我就想過三種方法,雖然不一定能達到要求,但是三種完全不同的方法,極大的鍛煉了我發散思維能力,使我學到了很多。對與如此簡單的一個通訊錄,已經讓我焦頭爛額,苦不堪言了,那些更高級的軟件該有多么復雜啊,不由得對程序員們產生了深深的敬意,也對自己的能力有了一個清晰的認識,我將繼續努力學習編程知識,我相信我能在這條路上走的更遠!
10:附錄:c語言代碼
1 #include
2 #include
3
4 structxinxi;5 structxinxi6 {7 intnum;8 char name[10];9 char address[10];10 };//個人信息結構體
11 typedef structxinxi Data;12
13 structhash{14 intmax;15 intlen;16 Data h[50];17 };//散列表
18 typedef struct hash *phash;19
20
21
22 /*
23 Menu() 的功能:顯示英文提示選單。24 Quit() 的功能:退出選單。25 /Create() 的功能:創建新的通訊錄。26 /Append() 的功能:在通訊錄寫入新的信息,并返回選單。27 /Find() 的功能:查詢某人的信息,如果找到了,則顯示該人的信息,如果沒有則提示通訊錄中沒有此人的信息,并返回選單。28 /Alter() 的功能:修改某人的信息,如果未找到要修改的人,則提示通訊錄中沒有此人的信息,并返回選單。29 /Delete() 的功能:刪除某人的信息,如果未找到要刪除的人,則提示通訊錄中沒有此人的信息,并返回選單。30 /List() 的功能:顯示通訊錄中的所有記錄。31 /Save() 的功能:保存通訊錄中的所有記錄到指定文件中。32 /Load() 的功能:從指定文件中讀取通訊錄中的記錄。33 */
34
35 ///
36 phash creat();37 intAppend(phash p,Data x);38 int find(phash p,int num,int *position);39 intalter(phash p);40 intDelete(phash p);41 intlist(phash p);42 intfindnum(phash p);43 intsave(phash p);44 intload(phash p);45 intstart(phash p);46 intnewnum(phash p);47 intmenu(phash p);48 /函數聲明49
50
51 /
52 phash creat(){53 inti;54 phash p=(phash)malloc(sizeof(structhash));55 if(p!=NULL){56 p->max=50;57 p->len=0;58 for(i=0;i<50;i++) {p->h[i].num=0;} //關鍵碼全部置零
59 returnp;60 }61 }62 ///創建散列表///63
64
65 66 intAppend(phash p,Data x){67 intposition;68 if(find(p,x.num,&position)==1)//散列表中已經存在
69 {70 printf("發現已經存在!\n");71 }72 else if(position!=-1){73 p->h[position]=x;//插入信息
74 p->len++;75 }76 else return 0;77 return 1;78 }79 //散列表的插入///80
81
82 /
83 int find(phash p,int num,int *position){84 intd,inc;85 d=num%50;//散列函數
86 for(inc=0;inc<50;inc++){87 if(p->h[d].num==num){88 *position=d;//檢索成功
89 return 1;90 }91 else if(p->h[d].num==0){92 *position=d;//檢索失敗
93 return 0;94 }95 d=(d+1)%50;96 }97 *position=-1;//散列表溢出
98 return 0;99 }100 /散列表的檢索//101
102
103
104 ///105 intalter(phash p){106 intnum;107 intposition;108 printf("輸入要修改的聯系人的號碼!\n");109 scanf("%d",&num);110
111 if(find(p,num,&position)==1){//檢索是否存在該聯系人
112 p->h[position].num=num;113 printf("請輸入需要修改的信息!(姓名 地址,空格隔開)\n");114 scanf("%s %s",&p->h[position].name,&p->h[position].address);115 }116 else
117 {118 printf("不存在該人!\n");119 }120
121 return 1;122 }123 /修改聯系人信息///124
125
126
127 //
128
129 intDelete(phash p){130 int num,i,j,r;//num:要刪除的聯系人號碼;j:標記空位;i:移動查找是否碰撞;r:i的聯系人號碼未發生碰撞時應在位置。
131 intposition;132 printf("輸入要刪除的聯系人的號碼!\n");133 scanf("%d",&num);134
135 if(find(p,num,&position)==1){136 i=position;137 for(;;){138 p->h[i].num=0;//刪除i產生一個空位。
139 j=i;//j存放空位位置,從后面的元素中選出一個元素填補空位
140 for(;;){141 i=(++i)%50;142 if(p->h[i].num==0)//若遇到未使用的位置則調整結束
143 {144 printf("聯系人已經刪除!\n");145 return 1;146 }147 r=p->h[i].num%50;//r為i位置中的元素未發生碰撞應在位置
148 ///149 //若r位于空位和當前位置i之間,則說明該元素不受影響,則跳出尋找下一個
150 if(ji && ji && r<=i)155 continue;156 //以上3條語句保證了r位于i與j之間
157 158 break;159 }160 p->h[j]=p->h[i];//將選擇的元素賦值到空位
161 }162
163
164
165 }166 else {printf("不存在該人!\n");}167 return 1;168 }169
170
171 /刪除聯系人/
172
173
174
175 176 intlist(phash p){177 inti;178 for(i=0;i<50;i++){179 if(p->h[i].num!=0)180 printf("%d\t%s\t%s\n",p->h[i].num,p->h[i].name,p->h[i].address);181 }182 return 1;183 }184 ///輸出所有聯系人//
185
186
187
188 ///
189 intsave(phash p){190 inti;191 FILE *fout;192 if((fout=fopen("xinxi.txt","w"))==NULL)//判斷文件是否存在
193 {194 printf("寫入文件失敗!\n");195 return 0;196 }197 for(i=0;i<50;i++)198 { if(p->h[i].num != 0)//判斷聯系人是否存在
199 fprintf(fout,"%d %s %s\n",p->h[i].num,p->h[i].name,p->h[i].address);//輸出存在的聯系人
200 }201 fclose(fout);//關閉文件
202 printf("文件已保存\n");203 return 1;204 }205 //保存聯系人到指定文件
206
207
208 ///
209 intload(phash p){210 FILE *fin;211 Data temp;212 inti;213 if((fin=fopen("xinxi.txt","r"))==NULL)//判斷文件是否存在
214 {215 printf("文件讀取失敗!\n");216 return 0;217 }218 while(!feof(fin))//判斷文件是否結束
219 {220 i=fscanf(fin,"%d %s %s",&temp.num,&temp.name,&temp.address);//讀取聯系人信息
221 if(i==-1) break;222 else Append(p,temp);//把讀取的信息插入散列表
223 }224 fclose(fin);225 printf("文件讀取成功\n");226 return 1;227 }228 ///讀取指定文件的信息229
230
231 /
232 intstart(phash p){233 inti;234 Data st;235 printf("請輸入三名聯系人的信息!(電話號碼,姓名,地址,空格隔開)\n");236 for(i=0;i<3;i++)237 {238 scanf("%d %s %s",&st.num,&st.name,&st.address);239 Append(p,st);240
241 }242 return 1;243 }244 初始化信息
245
246
247 //
248 intnewnum(phash p){249 intnum,position;250 Data n;251 printf("輸入要新建的聯系人的號碼!\n");252 scanf("%d",&num);253 if(find(p,num,&position)==1)//檢索聯系人是否存在
254 {printf("聯系人存在!\n");255 return 0;256 }257 else{258 n.num=num;259 printf("請輸入需要新建聯系人的信息!(姓名 地址,空格隔開)\n");260 scanf("%s %s",&n.name,&n.address);261 Append(p,n);262 printf("新建聯系人完成!\n");263 return 1;264 }265 }266 新建聯系人并插入散列表/267
268
269
270 ///271 intfindnum(phash p){272 inti,num,position;273 printf("輸入要查詢的聯系人的號碼!\n");274 scanf("%d",&num);275 if(find(p,num,&position)==1)276 {277 printf("%d\t%s\t%s\n",num,p->h[position].name,p->h[position].address);278 }279 else printf("要查找的聯系人不存在\n");280 return 1;281 }282 /查找聯系人并輸出信息//283
284
285
286 ///287 intmenu(phash p){288 inti;289
290 printf("********請輸入要進行的操作!*********\n\n0-退出通訊錄選單\n1-新建聯系人\n2-查找聯系人\n3-刪除聯系人\n4-修改聯系人的相關信息\n5-保存通訊錄至文件\n6-讀取文件中的聯系人信息\n7-顯示通信錄的全部信息\n");291 scanf("%d",&i);292
293 switch(i)294 {295 case 0: exit(0); break;296 case 1: newnum(p); break;297 case 2: findnum(p); break;298 case 3: Delete(p); break;299 case 4: alter(p); break;300 case 5: save(p); break;301 case 6: load(p); break;302 case 7: list(p); break;303 default : printf("選擇有誤!\n");304 }305 return 1;306 }307 ///選單///308
309
310 intmain(){311
312 inti;313 phash h;314 h=creat();315 printf("********************歡迎使用通訊錄存儲系統**************************\n");316 printf("* 當聯系人信息文件不存在時,請初始化通訊錄,存入聯系人的相關信息。*\n");317 printf("* 當聯系人信息文件存在時,請讀取信息文件。 *\n");318 printf("* 在執行完所有操作時,請保存文件后退出 *\n");319 printf("* 可存儲號碼50個 *\n");320 printf("* 號碼長度為5位 *\n");321 printf("* 姓名,地址為10個字符 *\n");322 printf("********************************************************************\n");323 printf("\n");324 printf("請選擇要進行的操作!1-初始化,2-讀取聯系人\n");325 scanf("%d",&i);326 if(i==1)327 start(h);328 else if(i==2)329 load(h);330 else
331 printf("輸入錯誤!\n");332 for(;;)333 {334 menu(h);335 }336 return 1;337 }
/
80
81
82 /
83 int find(phash p,int num,int *position){
84 int d,inc;
85 d=num%50;//散列函數
86 for(inc=0;inc<50;inc++){
87 if(p->h[d].num==num){
88 *position=d;//檢索成功
89 return 1;
90 }
91 else if(p->h[d].num==0){
92 *position=d;//檢索失敗
93 return 0;
94 }
95 d=(d+1)%50;
96 }
97 *position=-1;//散列表溢出
98 return 0;
99 }
100 /散列表的檢索//
101
102
103
104 ///
105 int alter(phash p){
106 int num;
107 int position;
108 printf("輸入要修改的聯系人的號碼!\n");
109 scanf("%d",&num);
110
111 if(find(p,num,&position)==1){//檢索是否存在該聯系人
112 p->h[position].num=num;
113 printf("請輸入需要修改的信息!(姓名 地址,空格隔開)\n");
114 scanf("%s %s",&p->h[position].name,&p->h[position].address);
115 }
116 else
117 {
118 printf("不存在該人!\n");
119 }
120
121 return 1;
122 }
123 /修改聯系人信息///
124
125
126
127 //
128
129 int Delete(phash p){
130 int num,i,j,r;//num:要刪除的聯系人號碼;j:標記空位;i:移動查找是否碰撞;r:i的聯系人號碼未發生碰撞時應在位置。
131 int position;
132 printf("輸入要刪除的聯系人的號碼!\n");
133 scanf("%d",&num);
134
135 if(find(p,num,&position)==1){
136 i=position;
137 for(;;){
138 p->h[i].num=0;//刪除i產生一個空位。
139 j=i;//j存放空位位置,從后面的元素中選出一個元素填補空位
140 for(;;){
141 i=(++i)%50;
142 if(p->h[i].num==0)//若遇到未使用的位置則調整結束
143 {
144 printf("聯系人已經刪除!\n");
145 return 1;
146 }
147 r=p->h[i].num%50;//r為i位置中的元素未發生碰撞應在位置
148 ///
149 //若r位于空位和當前位置i之間,則說明該元素不受影響,則跳出尋找下一個
150 if(j
151 continue;
152 if(j>i && j
153 continue;
154 if(j>i && r<=i)
155 continue;
156 //以上3條語句保證了r位于i與j之間
157
158 break;
159 }
160 p->h[j]=p->h[i];//將選擇的元素賦值到空位
161 }
162
163
164
165 }
166 else {printf("不存在該人!\n");}
167 return 1;
168 }
169
170
171 /刪除聯系人/
172
173
174
175
176 int list(phash p){
177 int i;
178 for(i=0;i<50;i++){
179 if(p->h[i].num!=0)
180 printf("%d\t%s\t%s\n",p->h[i].num,p->h[i].name,p->h[i].address);
181 }
182 return 1;
183 }
184 ///輸出所有聯系人//
185
186
187
188 ///
189 int save(phash p){
190 int i;
191 FILE *fout;
192 if((fout=fopen("xinxi.txt","w"))==NULL)//判斷文件是否存在
193 {
194 printf("寫入文件失敗!\n");
195 return 0;
196 }
197 for(i=0;i<50;i++)
198 { if(p->h[i].num != 0)//判斷聯系人是否存在
199 fprintf(fout,"%d %s %s\n",p->h[i].num,p->h[i].name,p->h[i].address);//輸出存在的聯系人
200 }
201 fclose(fout);//關閉文件
202 printf("文件已保存\n");
203 return 1;
204 }
205 //保存聯系人到指定文件
206
207
208 ///
209 int load(phash p){
210 FILE *fin;
211 Data temp;
212 int i;
213 if((fin=fopen("xinxi.txt","r"))==NULL)//判斷文件是否存在
214 {
215 printf("文件讀取失敗!\n");
216 return 0;
217 }
218 while(!feof(fin))//判斷文件是否結束
219 {
220 i=fscanf(fin,"%d %s %s",&temp.num,&temp.name,&temp.address);//讀取聯系人信息
221 if(i==-1) break;
222 else Append(p,temp);//把讀取的信息插入散列表
223 }
224 fclose(fin);
225 printf("文件讀取成功\n");
226 return 1;
227 }
228 ///讀取指定文件的信息
229
230
231 /
232 int start(phash p){
233 int i;
234 Data st;
235 printf("請輸入三名聯系人的信息!(電話號碼,姓名,地址,空格隔開)\n");
236 for(i=0;i<3;i++)
237 {
238 scanf("%d %s %s",&st.num,&st.name,&st.address);
239 Append(p,st);
240
241 }
242 return 1;
243 }
244 初始化信息
245
246
247 //
248 int newnum(phash p){
249 int num,position;
250 Data n;
251 printf("輸入要新建的聯系人的號碼!\n");
252 scanf("%d",&num);
253 if(find(p,num,&position)==1)//檢索聯系人是否存在
254 {printf("聯系人存在!\n");
255 return 0;
256 }
257 else{
258 n.num=num;
259 printf("請輸入需要新建聯系人的信息!(姓名 地址,空格隔開)\n");
260 scanf("%s %s",&n.name,&n.address);
261 Append(p,n);
262 printf("新建聯系人完成!\n");
263 return 1;
264 }
265 }
266 新建聯系人并插入散列表/
267
268
269
270 ///
271 int findnum(phash p){
272 int i,num,position;
273 printf("輸入要查詢的聯系人的號碼!\n");
274 scanf("%d",&num);
275 if(find(p,num,&position)==1)
276 {
277 printf("%d\t%s\t%s\n",num,p->h[position].name,p->h[position].address);
278 }
279 else printf("要查找的聯系人不存在\n");
280 return 1;
281 }
282 /查找聯系人并輸出信息//
283
284
285
286 ///
287 int menu(phash p){
288 int i;
289
290 printf("********請輸入要進行的操作!*********\n\n0-退出通訊錄選單\n1-新建聯系人\n2-查找聯系人\n3-刪除聯系人\n4-修改聯系人的相關信息\n5-保存通訊錄至文件\n6-讀取文件中的聯系人信息\n7-顯示通信錄的全部信息\n");
291 scanf("%d",&i);
292
293 switch(i)
294 {
295 case 0: exit(0); break;
296 case 1: newnum(p); break;
297 case 2: findnum(p); break;
298 case 3: Delete(p); break;
299 case 4: alter(p); break;
300 case 5: save(p); break;
301 case 6: load(p); break;
302 case 7: list(p); break;
303 default : printf("選擇有誤!\n");
304 }
305 return 1;
306 }
307 ///選單///
308
309
310 int main(){
311
312 int i;
313 phash h;
314 h=creat();
315 printf("********************歡迎使用通訊錄存儲系統**************************\n");
316 printf("* 當聯系人信息文件不存在時,請初始化通訊錄,存入聯系人的相關信息。*\n");
317 printf("* 當聯系人信息文件存在時,請讀取信息文件。 *\n");
318 printf("* 在執行完所有操作時,請保存文件后退出 *\n");
319 printf("* 可存儲號碼50個 *\n");
320 printf("* 號碼長度為5位 *\n");
321 printf("* 姓名,地址為10個字符 *\n");
322 printf("********************************************************************\n");
323 printf("\n");
324 printf("請選擇要進行的操作!1-初始化,2-讀取聯系人\n");
325 scanf("%d",&i);
326 if(i==1)
327 start(h);
328 else if(i==2)
329 load(h);
330 else
331 printf("輸入錯誤!\n");
332 for(;;)
333 {
334 menu(h);
335 }
336 return 1;
337 }
總結
以上是生活随笔為你收集整理的JAVA散列表个人通讯录_散列表实现简易通讯录的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用xcode devices安装卸载i
- 下一篇: 场效应管(MOS管)