链式存储结构来完成电话薄

链式存储结构来完成电话薄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;
}

猜你喜欢

转载自blog.csdn.net/weixin_43310774/article/details/85470357