Young87

SmartCat's Blog

So happy to code my life!

游戏开发交流QQ群号60398951

当前位置:首页 >跨站数据测试

数据结构-通讯录管理系统课程设计

任务:完成通讯录的一般性管理工作:
(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

上一篇: 赶紧收藏!程序员必备的工具网站,用好了节省你大把的编程时间

下一篇: Python如何使用Pygame画一个圆

精华推荐