链式存储结构来完成电话薄2019年1月3日

链式存储结构来完成电话薄2018年12月31日
以下内容仅供娱乐,欢迎随时探讨,请多指教
利用链式存储结构来完成电话薄的创建、查询、插入、删除、显示、排序以及修改等操作,具体要求如下:
1)利用尾部插入结点法建立电话薄;
2)完成在电话薄上按关键字查找即定位;
3)完成在电话薄上插入一条记录;
4)完成在电话薄上删除一条或多条记录;
5)完成电话薄的显示操作;
6)完成电话薄的排序操作;
7)完成电话薄的修改操作;

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"conio.h"
/*定义结构体*/
struct person {
	int num;//序号
	char name[20];
	__int64 phonenumber;// 使用 __int64 可以保持18位数的数字,电话11位足够
	__int64 phonenumberhome;// 使用 __int64 可以保持18位数的数字,电话11位足够
	struct person *next;
};

void delete_name(struct person *head,char sname[20]);//删除链表中值为name的结点,并返回链表的首指针
void sortlistl(struct person* head);//链表的排序降序姓名(冒泡法)
void sortlist(struct person* head);//链表的排序升序电话(冒泡法)
void insert(struct person *head,struct person *s);/*将s指向的结点插入链表,使链表保持升序,并返回头结点*/
struct person *chushihua(); //初始化链表
int sizeof_list(struct person* head);//获取链表长度(不包括头节点)
void delete_note(struct person *head,int num_x);/*删除链表中值为num的结点,并返回链表的首指针*/
void free_list(struct person *head);//释放链表
void savefile(struct person *head);//保存电话薄并退出程序
void output(struct person *head);/*输出链表各结点的值,也称对链表的遍历*/
struct person *search(struct person *head,char sname[20]);/*查找符合条件的结点,并返回指向该结点的指针*/
struct person *create_head(struct person *head);//创建带头结点的链表

/*(主函数)*/
int main()
{
	struct person *p , *head ;
	int c;
	int num ;
	char name[20];
	__int64 phonenumber ;
	printf("采用链式存储结构完成的电话薄\n");
	head=chushihua();
	while(1) {
		printf("1:创建电话薄  2:插入结点(自动升序)  3:输出电话薄 \n"
		       "4:查找联系人  5:删除结点(序号)  6:排序电话(升序) 7:排序姓名(降序)\n"
		       "8:修改联系人(以姓名为基准)  9:删除结点(姓名)\n"
		       "10:保存电话薄(并退出)!\n");
		scanf("%d",&c);
		switch(c) {
			case 1:
				head=create_head(head);
				break;
			case 2:
				printf("请分别输入要插入联系人的序号,姓名和电话号码:\n");
				scanf("%d%s%I64d",&num,name,&phonenumber);
				p=(struct person*)malloc( sizeof(struct person) );
				if(p==NULL) {
					printf("申请该结点失败!!!\n");
					break;
				}
				p->num=num;
				strcpy(p->name,name);
				p->phonenumber=phonenumber;
				insert(head,p);
				sortlistl(head);
				printf("插入成功!\n");
				break;
			case 3:
				output(head);
				break;
			case 4:
				printf("输入要查找的姓名\n");
				scanf("%s",name);
				p=search(head,name);
				if (p) {
					printf("该联系人信息为: ");
					printf("num=%d,name=%s,phonenumber=%I64d\n",p->num,p->name,p->phonenumber);
				} else
					printf("该联系人不存在\n");
				break;
			case 5:
				printf("请输入要删除的联系人的序号:\n");
				scanf("%d",&num);
				delete_note(head,num);
				break;
			case 6:
				sortlist(head);
				break;
			case 7:
				sortlistl(head);
				break;
			case 8:
				printf("请输入要修改联系人姓名:\n");
				scanf("%s",name);
				p=(struct person*)malloc(sizeof(struct person));
				p=search(head,name);
				printf("请分别输入要修改联系人的序号,姓名和电话号码:\n");
				scanf("%d%s%I64d",&num,name,&phonenumber);
				if(p == NULL) {
					printf("该联系人(姓名)不存在\n");
					break;
				}
				p->num=num;
				strcpy(p->name,name);
				p->phonenumber=phonenumber;
				printf("修改成功!\n");
				break;
			case 9:
				printf("输入要查找的姓名\n");
				scanf("%s",name);
				p=search(head,name);
				if (p) {
					printf("该联系人信息为: ");
					printf("num=%d,name=%s,phonenumber=%I64d\n",p->num,p->name,p->phonenumber);
					delete_name(head,name);
				} else
					printf("该联系人不存在\n");
				break;
			case 10:
				savefile(head);
				exit(0);
				break;
		}
	}
	return 0;
}

/*初始化链表*/
struct person *chushihua()
{
	struct person *head;
	head=(struct person*)malloc(sizeof (struct person));
	if(head==NULL) {
		printf("申请头结点失败!\n");
		return NULL;
	}
	head->next=NULL;
	return head;
}
/*创建带头结点的链表*/
struct person *create_head(struct person *head)
{
	int sno;
	struct person *p,*q;
	q=head;
	while(q->next) q=q->next;
	printf("请输入序号(序号输入负数结束): \n");
	scanf("%d",&sno);
	while(sno > 0) {
		p=(struct person*)malloc(sizeof(struct person));
		p->num=sno;
		printf("请输入姓名和电话号码:\n");
		scanf("%s%I64d",p->name,&p->phonenumber);
		q->next=p;
		q=p;
		printf("请输入序号(序号输入负数结束): \n");
		scanf("%d",&sno);
	}
	q->next=NULL;
	return head;
}
/*将s指向的结点插入链表,使链表保持升序,并返回头结点*/
void insert(struct person *head,struct person *s)
{
	struct person *p=head;
	while(p->next!=NULL && s->phonenumber>p->next->phonenumber)
//特别注意&&左右不能写反,小心短路,若s最大,最后p->next=NULL,p->next->phonenumber运行出错
		p=p->next;
	if(p->next == NULL) { //s->phonenumber最大的情况     //其实两种情况可以并在一块写
		p->next=s;      //连接结点
		s->next=NULL;   //p->next就等于NULL
	} else {
		s->next=p->next;
		p->next=s;    //连接结点,这两条语句不要写反
	}
}
/*查找符合条件的结点,并返回指向该结点的指针*/
struct person *search(struct person *head,char sname[20])
{
	struct person *p=head->next;
	while(p!=NULL && strcmp(p->name,sname) != 0)
//特别注意两条件不能写反,若写反最后p指向NULL时p->num找不到,运行出错
		p=p->next;
	return p;
}
/*输出链表各结点的值,也称对链表的遍历*/
void output(struct person *head)
{
	struct person *p;
	printf("\t联系人信息如下:\n");
	p=head->next;
	if(p == NULL) {
		printf("你还未创建!\n");
		return;
	}
	while(p) {
		printf("%d\t%s\t%I64d\n",p->num,p->name,p->phonenumber);
		p=p->next;
	}
}
//保存电话薄并退出程序
void savefile(struct person *head)
{
	struct person *p;
	FILE *fp;
	fp=fopen("c:\\aaAA\\person.txt","w");
	if(fp == NULL) {
		printf("无法打开,创建失败,请检查!\n");
		getch();
	} else {
		p=head->next;
		while(p) {
			fprintf(fp,"%d\t%s\t%I64d\n",p->num,p->name,p->phonenumber);
			p=p->next;
		}
		printf("创建保存成功!\n");
		free_list(head);
	}
	fclose(fp);
}
//释放链表
void free_list(struct person *head)
{
	struct person *p=head ;
	printf("释放链表:\n");
	while(p!=NULL) {
		head=head->next;
		free(p);
		p=head;
	}
	printf("释放链表成功!\n");
}
//删除链表中值为num的结点,并返回链表的首指针
void delete_note(struct person *head,int num_x)
{
	struct person *p1=head->next , *p2=head ;
	while(p1!=NULL && p1->num!=num_x) {
//特别注意&&左右条件不能调换,若调换如果p1指向NULL时p1->num运行出错
		p2=p1;
		p1=p1->next;
	}
	if(p1 == NULL)    return;
	p2->next=p1->next;
	free(p1);
	printf("删除成功!\n");
}
//删除链表中值为name的结点,并返回链表的首指针
void delete_name(struct person *head,char sname[20])
{
	struct person *p1=head->next , *p2=head ;
	while(p1!=NULL && strcmp(p1->name,sname) !=0) {
//特别注意&&左右条件不能调换,若调换如果p1指向NULL时p1->name运行出错
		p2=p1;
		p1=p1->next;
	}
	if(p1 == NULL)    return;
	p2->next=p1->next;
	free(p1);
	printf("删除成功!\n");
}
//获取链表长度(不包括头节点)
int sizeof_list(struct person *head)
{
	struct person* temp = head->next;
	int size = 0;
	while (temp) {
		size++;
		temp = temp->next;
	}
	return size;
}
//链表的排序升序电话(冒泡法)
void sortlist(struct person *head)
{
	int i,j, n = sizeof_list(head);
	struct person *p;
	int t;
	__int64 r;
	char cname[20];
	for (i=1; i<n; i++) {
		p=head->next;
		for (j=1; j <= n-i; j++) {
			if (p->phonenumber > p->next->phonenumber) {
				t=p->num,p->num=p->next->num,p->next->num=t;
				r=p->phonenumber,p->phonenumber=p->next->phonenumber,p->next->phonenumber=r;
				strcpy(cname,p->name),strcpy(p->name,p->next->name),strcpy(p->next->name,cname);
			}
			p=p->next;
		}
	}
	printf("排序成功!\n");
}
//链表的排序降序姓名(冒泡法)
void sortlistl(struct person* head)
{
	int i,j, n = sizeof_list(head);
	struct person *p;
	int t;
	__int64 r;
	char cname[20];
	for (i=1; i<n; i++) {
		p=head->next;
		for (j=1; j <= n-i; j++) {
			if (strcmp(p->name,p->next->name) < 0) {
				t=p->num,p->num=p->next->num,p->next->num=t;
				r=p->phonenumber,p->phonenumber=p->next->phonenumber,p->next->phonenumber=r;
				strcpy(cname,p->name),strcpy(p->name,p->next->name),strcpy(p->next->name,cname);
			}
			p=p->next;
		}
	}
	printf("排序成功!\n");
}
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值