链式存储结构来完成电话薄2018年12月31日
以下内容仅供娱乐,欢迎随时探讨,请多指教!
利用链式存储结构来完成电话薄的创建、查询、插入、删除、显示、排序以及修改等操作,具体要求如下:
1)利用尾部插入结点法建立电话薄;
2)完成在电话薄上按关键字查找即定位;
3)完成在电话薄上插入一条记录;
4)完成在电话薄上删除一条或多条记录;
5)完成电话薄的显示操作;
6)完成电话薄的排序操作;
7)完成电话薄的修改操作;
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
/*定义结构体*/
struct person {
int num;
float phonenumber;
struct person *next;
};
/*初始化链表*/
struct person *Init_List()
{
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;
float phonenumber;
struct person *p,*q;
q=head;
while(q->next) q=q->next;
printf("请输入电话号码和成绩,电话号码输入-1结束: ");
scanf("%d%f",&sno,&phonenumber);
while(sno>=0) {
p=(person *)malloc(sizeof(person));
p->num=sno;
p->phonenumber=phonenumber;
q->next=p;
q=p;
scanf("%d%f",&sno,&phonenumber);
}
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,int num)
{
struct person *p=head->next;
while(p!=NULL&&p->num!=num) //特别注意两条件不能写反,若写反最后p指向NULL时p->num找不到 运行出错
p=p->next;
return p;
}
/*输出链表各结点的值,也称对链表的遍历*/
void print(struct person *head)
{
struct person *p;
printf(" 链表如下: \n");
p=head->next;
while(p) {
printf("%d\t%.1f\n",p->num,p->phonenumber);
p=p->next;
}
}
/*释放链表*/
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);
}
//获取链表长度(不包括头节点)
int Size_List(struct person* head)
{
struct person* temp = head->next;
int size = 0;
while (temp) {
size++;
temp = temp->next;
}
return size;
}
//链表的排序(冒泡法)
void Sort_List(struct person* head)
{
int i,j, n = Size_List(head);
struct person *p;
int t;
float r;
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;
}
p=p->next;
}
}
}
/*完整的有头结点链表操作程序*/
int main()
{
struct person *p , *head ;
int c;
int num ;
float phonenumber ;
printf("有头结点链表操作程序:\n");
head=Init_List();
while(1) {
printf("1:创建链表 2:插入结点(自动升序) 3:输出链表 \n"
"4:查找结点 5:删除结点 6:排序 7:释放链表并退出程序! \n ");
scanf("%d",&c);
switch(c) {
case 1:
head=create_head(head);
break;
case 2:
printf("请分别输入要插入联系人的电话号码和分数:\n");
scanf("%d%f",&num,&phonenumber);
p=(struct person*)malloc( sizeof(struct person) );
if(p==NULL) {
printf("申请该结点失败!!!\n");
exit (0) ;
}
p->num=num;
p->phonenumber=phonenumber; //给p赋值
insert(head,p);
printf("插入成功!\n");
break;
case 3:
print(head);
break;
case 4:
printf("输入要查找的电话号码\n");
scanf("%d",&num);
p=search(head,num);
if (p) {
printf("该联系人信息为: ");
printf("num=%d,phonenumber=%f\n",p->num,p->phonenumber);
} else
printf("该联系人不存在\n");
break;
case 5:
printf("请输入要删除的联系人的电话号码:\n");
scanf("%d",&num);
delete_note(head,num);
break;
case 6:
Sort_List(head);
break;
case 7:
free_list(head);
exit (0);
}
}
return 0;
}