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