电话号码管理程序
這。。。是我的數據結構課程設計
題目要求是這個樣子的。。。
設計散列表(哈希表)實現電話號碼查找系統(tǒng)。
基本要求:?
1) 設每個記錄有下列數據項:電話號碼、用戶名、地址等相關信息;?
2) 從鍵盤輸入各記錄,分別以電話號碼和用戶名為關鍵字建立散列表;
3) 采用一定的方法解決沖突;
4) 查找并顯示給定電話號碼的記錄;
5) 查找并顯示給定用戶名的記錄。
6) 允許對記錄進行相關的增加,修改,刪除,。
擴展要求:?
1) 系統(tǒng)功能的完善;?
2) 設計不同的散列函數,比較沖突率;?
3) 在散列函數確定的前提下,嘗試各種不同類型處理沖突的方法,考察平均查找長度的變化。
其實。。。
我到現在也沒有弄明白為什么要分別以電話號碼和用戶名來建立哈希表呢。。。
搞不明白。。。
#include<stdio.h> #include<stdlib.h> #include<string.h> #define MAXSIZE 20 #define MAX_SIZE 20 //人名的最大長度 #define HASHSIZE 60 //定義表長 #define SUCCESS 1 #define UNSUCCESS -1 #include<iostream> using namespace std; typedef int Status; //為現有類型添加一個同義字 typedef char NA[MAX_SIZE];// typedef 掩飾數組類型 typedef struct//記錄 {NA name;NA address; //關鍵字NA tel; }humen; //查找表中記錄類型 typedef struct //建立哈希表 {humen *elem[HASHSIZE];//數據元素存儲基址int cou; //當前數據元素個數int siz; //當前容量 }HashTable; typedef struct //建立哈希表 {humen *elema[HASHSIZE];//數據元素存儲基址int cou2; //當前數據元素個數int siz2; //當前容量 }Hashtable; Status eq(char x[MAX_SIZE],char y[MAX_SIZE]) //比較兩個數組是否相等,若相等返回1,否則返回-1 {if(strcmp(x,y)==0)return 1;else return -1; } Status NUM_BER; //記錄的個數 全局變量 Status NUM_BER1; //記錄的個數 全局變量 void output(humen* a) //遍歷用戶的信息 {int i;system("cls");printf("姓名\t地址\t電話號碼");for( i=0;i<NUM_BER+NUM_BER1;i++){if(!a[i].name[0]=='\0')printf("\n%s\t%s\t\t%s",a[i].name,a[i].address,a[i].tel);}cout<<endl;system("pause");system("CLS"); } int Hash(char name[MAX_SIZE])//將輸入的字符數組轉換成ASCII碼后相加求和,然后取表長余數,并將余數值返回//一次探測 {int i,m;i = 1;m=(int)name[0]; //強制轉化成數字while(name[i]!='\0'){m+=(int)name[i];//余數i++;}m=m%HASHSIZE;return m; } int Hash2(char num[MAXSIZE]) {int i=0,key=0;while(i!=MAXSIZE)//關鍵字{key+=(num[i]-'0');//關鍵字求和i++;}key=key%HASHSIZE;return key; } Status collision(int p,int c)//沖突處理函數,采用二次探測法解決沖突//二次探測 {int i,q;i=c/2+1;while(i<HASHSIZE){if(c%2==0){c++;q=(p+i*i)%HASHSIZE;//倘若c為偶數,函數公式為:(余數+i*i)%表長,返回合理值if(q>=0)return q;elsei=c/2+1;}else{q=(p-i*i)%HASHSIZE;//若c為奇數,函數公式為:(余數-i*i)%表長,返回合理值c++;if(q>=0) return q;else i=c/2+1;}}return UNSUCCESS; }void CreateHash(HashTable* H,humen* a,int m)//建表,以人的姓名為關鍵字,建立相應的哈希表 {int i,p=-1,c=0,pp;cout<<"以姓名為關鍵字建立哈希表"<<endl;for(i=0;i<m;i++){c=0; //記錄沖突次數的變量p=Hash(a[i].name);pp=p;while(H->elem[pp]!=NULL) //若不為空,即產生沖突,調用沖突處理函數{pp=collision(p,c); //若哈希地址沖突,進行沖突處理c++;if(pp<0){printf("第%d記錄無法解決沖突",i+1);//需要顯示沖突次數時輸出continue; //無法解決沖突,跳入下一循環(huán)}}H->elem[pp]=&(a[i]); //求得哈希地址,將信息存入H->cou++; //表當前數據個數+1printf("第%d個記錄沖突次數為%d。\n",i+1,c);} } void CreateHash2(Hashtable* H,humen* a,int m) //建表,以人的姓名為關鍵字,建立相應的哈希表 {int i,p=-1,c=0,pp;cout<<"以電話號碼為關鍵字建立哈希表"<<endl;for(i=0;i<m;i++){c=0; //記錄沖突次數的變量p=Hash2(a[i].tel);pp=p;while(H->elema[pp]!=NULL) //若不為空,即產生沖突,調用沖突處理函數{pp=collision(p,c); //若哈希地址沖突,進行沖突處理c++;if(pp<0){printf("第%d記錄無法解決沖突",i+1); //需要顯示沖突次數時輸出continue; //無法解決沖突,跳入下一循環(huán)}}H->elema[pp]=&(a[i]); //求得哈希地址,將信息存入H->cou2++; //表當前數據個數+1printf("第%d個記錄沖突次數為%d。\n",i+1,c);} } void Create(HashTable* H,humen* a,Hashtable* H2) //創(chuàng)建新的通訊錄 {system("CLS");//調用DOS命令CLS能夠清屏memset(a->tel,0,sizeof(a->tel));printf("\n輸入要添加的個數:\n");scanf("%d",&NUM_BER);for(int i=0;i<NUM_BER;i++) //輸入創(chuàng)建的用戶信息{printf("請輸入第%d個記錄的姓名:\n",i+1);scanf("%s",a[i].name);printf("請輸入%d個記錄的地址:\n",i+1);scanf("%s",a[i].address);printf("請輸入第%d個記錄的電話號碼:\n",i+1);scanf("%s",a[i].tel);}printf("添加成功!!!\n");CreateHash(H,a,NUM_BER);CreateHash2(H2,a,NUM_BER);system("pause");system("CLS"); } void add(humen* a,humen *b,HashTable* H,Hashtable* H2) //增加新的通訊錄 {memset(b->tel,0,sizeof(b->tel));system("CLS"); //調用DOS命令CLS能夠清屏printf("\n輸入要添加的個數:\n");scanf("%d",&NUM_BER1);for(int i=0;i<NUM_BER1;i++) //輸入創(chuàng)建的用戶信息{printf("請輸入第%d個記錄的姓名:",i+1);scanf("%s",b[i].name);for(int j=0;j<MAXSIZE;j++){a[i+NUM_BER].name[j]=b[i].name[j];}printf("請輸入%d個記錄的地址:",i+1);scanf("%s",b[i].address);for(int j=0;j<MAXSIZE;j++){a[i+NUM_BER].address[j]=b[i].address[j];}printf("請輸入第%d個記錄的電話號碼:",i+1);scanf("%s",b[i].tel);for(int j=0;j<MAXSIZE;j++){a[i+NUM_BER].tel[j]=b[i].tel[j];}}printf("添加成功!!!\n");CreateHash2(H2,b,NUM_BER1);CreateHash(H,b,NUM_BER1);system("pause");system("CLS"); }void SearchHash(HashTable* H,int c,humen *a,Hashtable* H2) //在通訊錄里查找姓名關鍵字,c用來記錄沖突次數,若查找成功,顯示信息 {int i;int p,pp;NA NAME; //定義要查找的名字的字符數組system("cls");int l;cout<<"1.按姓名查找"<<endl;cout<<"2.按電話號碼查找"<<endl;cout<<"請輸入你的選項"<<endl;cin>>l;switch(l){case 1:do{printf("\n請輸入要查找記錄的姓名:\n");scanf("%s",NAME);p=Hash(NAME); //調用一次探測函數pp=p;while((H->elem[pp]!=NULL)&&(eq(NAME,H->elem[pp]->name)==-1))//倘若一探測結果和所要查找的結果不同,調用二次探測函數{pp=collision(p,c);c++; //沖突次數增加}if(H->elem[pp]!=NULL&&eq(NAME,H->elem[pp]->name)==1) //探測到結果后將信息輸出{printf("\n查找成功!\n查找過程沖突次數為%d.以下是您需要要查找的信息:\n\n",c);printf("姓名:%s\n地址:%s\n電話號碼:%s\n",H->elem[pp]->name,H->elem[pp]->address,H->elem[pp]->tel);}else printf("\n此人不存在,查找不成功!\n");cout<<"是否繼續(xù)查找?1.繼續(xù)0.退出"<<endl;cin>>i;}while(i!=0);system("pause");system("CLS");break;case 2:do{memset(NAME,0,sizeof(NAME));//初始化printf("\n請輸入要查找記錄的電話號碼:\n");scanf("%s",NAME);p=Hash2(NAME); //調用一次探測函數pp=p;while((H2->elema[pp]!=NULL)&&(eq(NAME,H2->elema[pp]->tel)==-1))//倘若一探測結果和所要查找的結果不同,調用二次探測函數{pp=collision(p,c);c++; //沖突次數增加}if(H2->elema[pp]!=NULL&&eq(NAME,H2->elema[pp]->tel)==1) //探測到結果后將信息輸出{printf("\n查找成功!\n查找過程沖突次數為%d.以下是您需要要查找的信息:\n\n",c);printf("姓名:%s\n地址:%s\n電話號碼:%s\n",H2->elema[pp]->name,H2->elema[pp]->address,H2->elema[pp]->tel);}else printf("\n此人不存在,查找不成功!\n");cout<<"是否繼續(xù)查找?1.繼續(xù)0.退出"<<endl;cin>>i;}while(i!=0);system("CLS");break;default:break;} }void Modify(HashTable *H,int c,humen* a)//在通訊錄里修改某人信息 {int p,pp;NA NAME; //想要修改的姓名數組system("cls");cout<<"輸入你所要修改的原用戶名"<<endl;scanf("%s",NAME);p=Hash(NAME); //調用一次探測函數pp=p;while((H->elem[pp]!=NULL)&&(eq(NAME,H->elem[pp]->name)==-1)) //倘若一探測結果和所要查找的結果不同,調用二次探測函數pp=collision(p,c);if(H->elem[pp]!=NULL&&eq(NAME,H->elem[pp]->name)==1) //探測到結果后修改信息{int m;do{cout<<"修改信息"<<endl;cout<<"1.修改姓名"<<endl;cout<<"2.修改地址"<<endl;cout<<"3.修改電話號碼"<<endl;cout<<"請選擇你想要選擇的選項,輸入0結束修改此用戶信息"<<endl;cin>>m;if(m==1){int p,n=0,m,i;printf("請輸入修改后記錄的姓名:\n");scanf("%s",H->elem[pp]->name);NA t;for(int i=0;i<MAXSIZE;i++){t[i]=H->elem[pp]->name[i];}p=Hash(t);m=p;while(H->elem[m]!=NULL)//若不為空,即產生沖突,調用沖突處理函數{m=collision(p,n); //若哈希地址沖突,進行沖突處理n++;if(m<0){cout<<"沖突無法解決"<<endl;break;}}H->elem[m]=H->elem[pp]; //求得哈希地址,將信息存入}if(m==2){printf("請輸入修改后記錄的地址:\n");scanf("%s",H->elem[pp]->address);}if(m==3){printf("請輸入修改后記錄的電話號碼:\n");scanf("%s",H->elem[pp]->tel);}}while(m!=0);printf("修改成功!\n");}elseprintf("此人不存在,修改不成功!\n");system("CLS"); } void Delete(HashTable* H,int c,humen* a) //在通訊錄里查找姓名關鍵字,若查找成功,顯示信息然后刪除 {int i;do{int m,p,pp;NA NAME;m=0;system("cls");printf("請輸入要刪除記錄的姓名:\n");m++;scanf("%s",NAME);//輸入想要刪除的記錄的名字p=Hash(NAME);pp=p;while((H->elem[pp]!=NULL)&&(eq(NAME,H->elem[pp]->name)==-1))//倘若一探測結果和所要查找的結果不同,調用二次探測函數pp=collision(p,c);if(H->elem[pp]!=NULL&&eq(NAME,H->elem[pp]->name)==1)//探測到結果后刪除信息{printf("以下是您需要要刪除的信息:\n\n",c);printf("姓名:%s\n地址:%s\n電話號碼:%s\n",H->elem[pp]->name,H->elem[pp]->address,H->elem[pp]->tel);for(int i=0;i<NUM_BER+NUM_BER1;i++){if(eq(NAME,a[i].name)==1){a[i].name[0]='\0';}}H->elem[pp]->name[0]='\0';//將所要刪的用戶的電話號碼清空H->elem[pp]->address[0]='\0';H->elem[pp]->tel[0]='\0';cout<<"1"<<H->elem[pp]->name[0]<<"1"<<endl;printf("刪除成功!!!\n");}elseprintf("此人不存在,刪除不成功!\n");cout<<"是否繼續(xù)刪除?1.繼續(xù)0.退出"<<endl;cin>>i;}while(i!=0);system("CLS"); } int main() {int c,i=0;humen a[MAXSIZE];//結構體數組變量humen b[MAXSIZE];HashTable *H;//哈希表指針變量Hashtable *H2;H2=(Hashtable*)malloc(sizeof(Hashtable));//申請空間for(i=0;i<HASHSIZE;i++)//初始化哈希表{H2->elema[i]=NULL;H2->siz2=HASHSIZE;H2->cou2=0;}H=(HashTable*)malloc(sizeof(HashTable));//申請空間for(i=0;i<HASHSIZE;i++) //初始化哈希表{H->elem[i]=NULL;H->siz=HASHSIZE;H->cou=0;}while (1)//菜單目錄{int num;printf("***************************通訊錄****************************");printf("\n* 【1】. 創(chuàng)建用戶信息 *");printf("\n* 【2】. 添加用戶信息 *");printf("\n* 【3】. 顯示所有用戶信息 *");printf("\n* 【4】. 查找用戶信息 *");printf("\n* 【5】. 刪除用戶信息 *");printf("\n* 【6】. 修改用戶信息 *");printf("\n* 【7】. 退出程序 *");printf("\n*****************************************************************");printf("\n");printf("\n請輸入一個任務選項>>>");printf("\n");scanf("%d",&num);switch(num){case 1:Create(H,a,H2) ;break;case 2:add(a,b,H,H2) ;break;case 3:output(a);break;case 4:c=0;SearchHash(H,c,a,H2);break;case 5:c=0;Delete(H,c,a);break;case 6:c=0;Modify(H,c,a);break;case 7:return 0;break;default:printf("輸入錯誤,請重新輸入!");printf("\n");} }system("pause");return 0; }總結
- 上一篇: tomcat内存溢出:PermGen s
- 下一篇: python高级编程技巧