数据结构-通讯录管理系统课程设计
日期: 2020-06-26 分类: 跨站数据测试 402次阅读
任务:完成通讯录的一般性管理工作:
(1)添加信息;
(2)显示信息:可以按照手机或联系人的姓名拼音排序显示;
(3)查找:可用不同的关键字作为查找的依据,进行查找;
(4)编辑信息;
(5)删除信息;
(6)保存到文件;
要求:
(1)界面友好,可反复操作。
(2)每条记录至少包括姓名、手机、QQ、电子邮箱、城市、邮编等信息。
主要的子函数有:
int HandleCollision(HashTable table,int key) /冲突处理/
void CreateHashTable(HashTable &table,Record *record,int n) /*构建哈希表 */
void Print(Record record[],int k) /打印联系人信息/
void GoToFile(HashTable table) /将哈希表存入文件中/
void displayName(Record record[],int k) /按姓名排序显示/
void displayNum(Record record[],int k) /按电话排序显示/
void findname(Record record[],int k) /按姓名查找/
int SerchKey(HashTable table,char PhoneNumber[])/按照电话号码查找/
void Modify(Record record[],int k) /修改联系人信息/
int Add(Record record[],int k) /*添加联系人信息 */
int Delete(Record record[],int k) /删除联系人信息/
代码:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define MAXSIZE 50
using namespace std;
int Czy=1;
//定义信息的结构体
typedef struct record
{
char Number[20];//电话
char Name[20];//姓名
char Address[20];//地址
char Classification[20];//分类(家人,朋友,同学,老师)
char QQ[20];//qq
char Email[20];//电子邮箱
char Postcode[10];//邮编
}Record;
//定义一个散列表
typedef struct Hash
{
Record *data;//存放多条记录的数组
int cnt;
int size;//数组大小
}*HashTable,HashElem;
Record record[50];
//哈希函数,将电话号码每一位求和
int GetHashKey(char ar[])
{
int len=strlen(ar); //计算电话号码的长度
int key=0;
for(int i=0;i<len;i++){
key+=ar[i]-'0'; //key=总和,数字字符减'0'就是数字
}
return key%MAXSIZE;//必须取模,否则下标越界
//返回得到的地址
}
//冲突处理,二次探测再散列
int HandleCollision(HashTable table,int key)
{
Czy=1; //从2,3,4,5,.......
while(1){
Czy++; //从2,3,4,5,.......
if(Czy%2==0) { //偶数和偶数下一个数奇数除二的值相等
if(table->data[(key+(Czy/2)*(Czy/2))%MAXSIZE].Name[0]==0) //如果这个位置上没有数据
return (key+(Czy/2)*(Czy/2))%MAXSIZE; //返回这个位置上的地址
}
else if(Czy%2!=0) {
if((key-(Czy/2)*(Czy/2))<0) continue;//由于是减法,要注意负数不能取模
if(table->data[(key-(Czy/2)*(Czy/2))%MAXSIZE].Name[0]==0)
return (key-(Czy/2)*(Czy/2))%MAXSIZE;
}
}
}
//构建哈希表
void CreateHashTable(HashTable &table,Record *record,int n)
{
int key;
for(int i=0;i<n;i++){
key=GetHashKey(record[i].Number); //接受每个电话返回来的地址
if(table->data[key].Name[0]!=0) //当这个地址里的名字不为空时,也就是有冲突了
key=HandleCollision(table,key); //进行冲突处理 传冲突的地址
//如果不冲突,则进行赋值
strcpy(table->data[key].Number,record[i].Number);
strcpy(table->data[key].Name,record[i].Name);
strcpy(table->data[key].Address,record[i].Address);
strcpy(table->data[key].Classification,record[i].Classification);
strcpy(table->data[key].QQ,record[i].QQ);
strcpy(table->data[key].Email,record[i].Email);
strcpy(table->data[key].Postcode,record[i].Postcode);
}
}
//打印联系人信息
void Print(Record record[],int k)
{
int i;
printf("---------------------------联系人信息-----------------------------\n\n");
printf(" 姓名 电话 地址 分类 QQ 电子邮箱 邮编\n\n");
//按格式输出到屏幕 固定宽度
for(i=0;i<k;i++)//遍历数组 依次打印
{
printf("%s %s %s %s %s %s %s\n",record[i].Name,
record[i].Number,record[i].Address,record[i].Classification,
record[i].QQ,record[i].Email,record[i].Postcode);
}
}
//将哈希表存入文件中
void GoToFile(HashTable table)
{
FILE *fp=fopen("Output.txt","w"); //打开文件Output.txt
for(int i=0;i<=MAXSIZE;i++) //遍历整个散列表
if(table->data[i].Name[0]!=0) //如果名字不为空,则写入文件
fprintf(fp,"%s %s %s %s %s %s %s\n",table->data[i].Name,table->data[i].Number
,table->data[i].Address,table->data[i].Classification,table->data[i].QQ,
table->data[i].Email,table->data[i].Postcode);
fclose(fp); //关闭文件
}
//按姓名排序显示
void displayName(Record record[],int k)
{
int i,j;
Record temp;
for(i=0;i<k;i++)
{
for(j=i+1;j<k;j++)//冒泡排序
{
if(strcmp(record[i].Name,record[j].Name)<0)
{
temp=record[i];
record[i]=record[j];
record[j]=temp;
}
}
}
}
//按电话排序显示
void displayNum(Record record[],int k)
{
int i,j;
Record temp;
for(i=0;i<k;i++)
{
for(j=i+1;j<k;j++)
{
if(strcmp(record[i].Number,record[j].Number)<0)
{
temp=record[i];
record[i]=record[j];
record[j]=temp;
}
}
}
}
//按姓名查找
void findname(Record record[],int k)
{
int i,flag=0;
char temp[20];
printf("请输入要查询的联系人姓名: ");
scanf("%s",temp);
for(i=0;i<k;i++)
{
if(!strcmp(temp,record[i].Name))//如果名字相同
{
Print(&record[i],1);//输出信息
flag=1;
}
}
if(flag==0)
{
printf("无该联系人!\n");
system("pause");
return ;
}
system("pause");
}
//按照电话号码查找
int SerchKey(HashTable table,char PhoneNumber[])
{
int key=GetHashKey(PhoneNumber); //得到该元素的最初地址位置
if(strcmp(table->data[key].Number,PhoneNumber)){
//如果该位置上的数与给定的数不相等,则考虑冲突寻址
for(Czy=1;Czy<MAXSIZE;Czy++){
if(Czy%2==0) {
if(!strcmp(PhoneNumber,table->data[(key+(Czy/2)*(Czy/2))%MAXSIZE].Number)){
//如果相等则地址就等于冲突处理后的值
key= (key+(Czy/2)*(Czy/2))%MAXSIZE;
break;
}
}
else if(Czy%2!=0) {
if((key-(Czy/2)*(Czy/2))<0) continue;//由于是减法,要注意负数不能取模
//如果取差后为负数,则不做处理,Czy+1
//不是负数,判断值是否与当前地址值相等
if(!strcmp(PhoneNumber,table->data[(key-(Czy/2)*(Czy/2))%MAXSIZE].Number)){
key= (key-(Czy/2)*(Czy/2))%MAXSIZE;
break;
}
}
}
}
printf("---------------------------联系人信息-----------------------------\n\n");
printf(" 姓名 电话 地址 分类 QQ 电子邮箱 邮编\n\n");
printf("%s %s %s %s %s %s %s\n",table->data[key].Name,
table->data[key].Number,table->data[key].Address,table->data[key].Classification,
table->data[key].QQ,table->data[key].Email,table->data[key].Postcode);
}
void findnumb(HashTable numbertable){ //查询函数
int key = 0;
//输入并寻找PhoneNumber(必须存在表中)
char PhoneNumber[20];
printf("请输入你想找的电话: ");
cin >> PhoneNumber;
cout << "给定电话号码为:" << endl << PhoneNumber << endl;
key= SerchKey(numbertable, PhoneNumber);
if (!strcmp(numbertable->data[key].Number, PhoneNumber))
printf("找到的电话信息为:\n");
}
void savenumb(HashTable numbertable,Record record[],int k){ //保存函数
for (int i = 0; i < k; i++){
printf("第%d位联系人信息: \n", i+1);
printf("请输入姓名: ");cin >> record[i].Name;
printf("请输入电话: ");cin >> record[i].Number;
printf("请输入住址: ");cin >> record[i].Address;
printf("请输入分类: ");cin >> record[i].Classification;
printf("请输入QQ号: ");cin >> record[i].QQ;
printf("请输入Email: ");cin >> record[i].Email;
printf("请输入邮编: ");cin >> record[i].Postcode;
}
//创建哈希表
CreateHashTable(numbertable, record, k);
}
//修改联系人信息
void Modify(Record record[],int k)
{
int i;
char temp[20];
Record swap;
printf("请输入要修改的联系人姓名: ");
scanf("%s",temp);
for(i=0;i<k;i++)
{
if(!strcmp(temp,record[i].Name))
break;
}
if(i==k)
{
printf("无该联系人!\n");
system("pause");
return ;
}
Print(&record[i],1);
printf("请输入电话: ");cin >> swap.Number;
printf("请输入住址: ");cin >> swap.Address;
printf("请输入分类: ");cin >> swap.Classification;
printf("请输入QQ号: ");cin >> swap.QQ;
printf("请输入Email: ");cin >> swap.Email;
printf("请输入邮编: ");cin >> swap.Postcode;
printf("是否确认修改Y/N?: ");
scanf("%s",temp);
if(!strcmp(temp,"Y")||!strcmp(temp,"y"))
{
strcpy(swap.Name,record[i].Name);
record[i]=swap;
printf("修改成功!\n");
system("pause");
return ;
}
printf("已取消修改!\n");
system("pause");
}
//添加新的联系人到结构体数组
int Add(Record record[],int k)
{
printf("请输入姓名: ");cin >> record[k].Name;
printf("请输入电话: ");cin >> record[k].Number;
printf("请输入住址: ");cin >> record[k].Address;
printf("请输入分类: ");cin >> record[k].Classification;
printf("请输入QQ号: ");cin >> record[k].QQ;
printf("请输入Email: ");cin >> record[k].Email;
printf("请输入邮编: ");cin >> record[k].Postcode;
printf("添加成功!\n");
system("pause");
return k+1;//结构体数组长度+1
}
//删除联系人信息
int Delete(Record record[],int k)
{
int i,j;
char temp[20];
printf("请输入要删除的联系人姓名: ");
scanf("%s",temp);
for(i=0;i<k;i++)//遍历结构体数组
{
if(!strcmp(temp,record[i].Name))//如果查找到 跳出循环
break;
}
if(i==k)//如果一直没有跳出循环 说明没有找到
{
printf("无该联系人!\n");
system("pause");
return k;//返回原人数
}
Print(&record[i],1);
printf("是否删除Y/N?: ");
scanf("%s",temp);
if(!strcmp(temp,"Y")||!strcmp(temp,"y"))//如果选择Y
{
for(j=i;j<k;j++)//用后面的元素覆盖前面的
{
record[j]=record[j+1];
}
printf("删除成功!\n");
system("pause");
return k-1;//长度减一
}
printf("已取消删除!\n");
system("pause");
return k;
}
void menu()
{
printf("\n ******************************************\n");
printf(" ********* 通讯录管理系统 *********\n");
printf(" **** 1 ------新建联系人信息 ****\n");
printf(" **** 2 ------打印联系人信息 ****\n");
printf(" **** 3 ------按姓名排序显示 ****\n");
printf(" **** 4 ------按电话排序显示 ****\n");
printf(" **** 5 ------按姓名查找 ****\n");
printf(" **** 6 ------按电话查找 ****\n");
printf(" **** 7 ------修改联系人信息 ****\n");
printf(" **** 8 ------添加联系人信息 ****\n");
printf(" **** 9 ------删除联系人信息 ****\n");
printf(" **** 10 ------保存到文件 ****\n");
printf(" **** 0 ------退出 ****\n");
printf(" ******************************************\n\n");
}
int main(){
//定义及初始化
//Record record[50]; //定义结构体数组,可以存放50个元素的信息
HashElem table; //散列表结构体变量
HashTable numbertable; //散列表结构体指针
numbertable = &table; //给结构体指针赋初值
numbertable->data = (Record*)malloc(sizeof(record[0])*MAXSIZE);
memset(numbertable->data, 0, sizeof(record[0])*MAXSIZE);
numbertable->size = MAXSIZE;
numbertable->cnt = 0;
int input;
do{
menu();
int n;
printf("请输入你想要执行的操作\n");
scanf("%d", &input);
switch (input)
{
case 1:
//输入数据组数
printf("你想要存入多少人的联系信息?\n");
cin >> n;
while(n > 10){
printf("一次只能存放10位联系人\n");
printf("请重新输入:\n");
cin >> n;
}
savenumb(numbertable, record,n);
break;
case 2:Print(record,n);
break;
case 3:
displayName(record,n);
Print(record,n);
break;
case 4:
displayNum(record,n);
Print(record,n);
break;
case 5:findname(record,n);
break;
case 6:findnumb(numbertable);
break;
case 7:Modify(record,n);
break;
case 8:Add(record,n);
break;
case 9:Delete(record,n);
break;
case 10:
//存入文件中
GoToFile(numbertable);
printf("文件保存成功!\n");
break;
case 0:
printf("退出通讯录!\n");
break;
default:
printf("你的输入有误请重新输入!\n");
break;
}
} while (input);
system("pause");
return 0;
}
界面显示
除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog
标签:数据结构
精华推荐