期末C语言链表复习(2)

学生信息(链表实现)
参考题目:C语言程序设计第五版学习辅导 第九章(具体哪一题记不清了QAQ)
//实现链表的建立,输出,删除。插入
#include<stdio.h>
#include<stdlib.h>
#define LEN sizeof(struct student)//四个子函数 
struct student
{
    char num;
	float score;
	struct student *next;//首先定义结构体变量(学号,分数,*next作为一个承上启下的变量,同时需要被定义在结构体变量中) 
};
int n;
int main()
{
	struct student*creat(); //创建学生信息的函数的声明 
	struct student*del(student*,char num );//删除学生相关信息的函数的声明 
	struct student*insert( student *, student*);//插入学生相关信息的函数的声明 
	void print( student*);//输出学生相关信息的函数的声明 
	struct student *head,*stu;//结构体变量。一堆学生和我想要增加的那个学生 
	char del_num;//定义想要删除的学生对应的学号 
	printf("input records:\n");
	head=creat();//创建链表给一个头指针接着 
	print(head);//输出我所创建的那个学生信息链表 
	printf("\ninput the delete number:");
	scanf("%s",&del_num);//读取我先要删除的那个学生的信息 
	while(del_num!=0)//判断这个学生的学号是否为0,如果学号为零,则不进行如下循环,如果不是零 
	{
		head=del(head,del_num);//调用删除学生信息的子函数,把改完后的链表传给Head接着 
		print(head);//输出新的head 
		printf("input the deleted number:");
		scanf("%s",&del_num);//由于我可以删除的学生信息不止一个,所以我可以把读取学生信息这句话放在外面一个,放在循环里一个 
	}
	printf("\ninput the inserted record:");
	stu=(struct student *)malloc(LEN);//由于涉及到一个新的学生的相关信息,所以要开辟一个新的存储单元 
	scanf("%s,%f",&stu->num,&stu->score);//读取这个新的学生的学号,成绩 
	while(stu->num!=0)//进行判断这个学生的学号是否为0,如果是零则不进行这个循环,如果不是零,进行如下循环 
	{
		head=insert(head,stu);//调用增加一个学生信息的函数 
		print(head);//输出新的链表 
		printf("input the inserted recored:");//由于可以增加的学生不止一个,所以把读取学号这个部分既放在了循环里面,又放在了循环外面 
		stu=(struct student*)malloc(LEN);
		scanf("%s,%f",&stu->num,&stu->num);
	}
	return 0;
}
	struct student *creat()//链表的创建 
	{
		struct student *head;//定义一个头指针 
		struct student *p1,*p2;//两个过程中需要用的指针p1,p2 
		n=0;//定义计数变量n的初值为0 
		p1=p2=(struct student *)malloc(LEN);// 使得两个过程指针p1,p2指向同一个,并同步开启一个存储单元 
		scanf("%s,%f",&p1->num,&p1->score);//向链表中传初始值,传结构体中的学号,成绩 
		head=NULL;//让头指针指空 
		while(p1->num!=0)//由于之前已经开辟了存储单元,所以p1有处可指,如果输入的学号是0,则不进入这个while循环,当学号不是零的前提下,进行while循环 
		{
			n++;//每进行一次循环计数变量n的值都会+1 
			if(n==1)//计数变量的值为1时,证明让头指针和p1指向同一个位置 
			head=p1;
			else
			p2->next=p1;//如果计数变量的值不是1,就让p2的末尾和p1连着,让p2跟着p1走 
			p2=p1;
			p1=(struct student*)malloc(LEN);//利用p1再次开辟一个新的存储单元 
			scanf("%s,%f",&p1->num,&p1->score);//再次读取学号和成绩 
		}
		p2->next=NULL;//准备收尾,让p2的末端与空连着,链表建立完毕,返回头指针 
		return (head);
	}
	struct student*del(student*head,char num)//链表中数据的删除 
	{
		struct student *p1,*p2;//由于在第一个创建链表的函数中,已经存在了head这个指针,所以不需要再次定义,但是由于p1,p2属于过程指针变量,所以需要再次定义 
		if(head==NULL)//首先考虑已知的链表是否为空,如果已知的链表是空的,直接输出链表为空这句话,然后返回头指针 
		{
			printf("\nlist null! \n");
			return head;
		}
		p1=head;//如果链表不是空的,那么让p1指针作为头指针 
		while(num!=p1->num&&p1->next!=NULL)//由于这个子函数传进来的参数中有一个num,说明num是我想要删除的,然后遍历链表,你不是我想找的,你也不是最后一个,那么就进行这个while循环 
		{
			p2=p1;//
			p1=p1->next;//这两句话就是p2跟着p1跑 
			}
			if(num==p1->num)//如果碰到了想要找的那个目标值 
			{
				if(p1==head)//如果想要找的那个值恰好是第一个链表对应的值 
				head=p1->next;//说明链表只有一个部分,把链表进行自锁 
				else//如果我想找的不是第一个 
				p2->next=p1->next;//让p2把p1覆盖掉,类似于覆盖重组链表 
				printf("delete:%s\n",num);//输出我想要删除的那个学生的信息 
				n--;//学生数减一 
			}
			else//如果依旧没有碰到想要找的那个目标值 ,就输出没找到 
			printf("%s not been found!\n",num);
			return(head);//返回头指针 
	 } 
	 struct student*insert(struct student *head,struct student *stud)//插入一个学生的信息,需要传进来的参数有原来的链表中含有学生信息的头指针,新的学生的链表信息 
	 {
	 	struct student *p0,*p1,*p2;//由于有了一个新的学生的信息,所以不仅需要之前所用的过程指针p1,p2,还需要一个新的指针p0作为传输的媒介 
	 	p1=head;//和之前一样,让p1作为头指针指向第一个同学的信息 
	 	p0=stud;//让我们新定义的p0指向新的同学的个人信息 
	 	if(head==NULL)//如果第一个链表是空的 
	 	{
	 		head=p0;//那么让我们新插入的那个同学的信息直接作为链表的组成 
	 		p0->next=NULL;//链表收尾 
	 	}
	 	else//如果链表不是空的 
	 	{
	 		while((p0->num>p1->num)&&(p1->next!=NULL))//如果我想要插入的那个学生对应的学号比p1指向的序号大,而且p1的下个单元不是空的 
	 		{
	 			p2=p1;//那么就让p2紧紧地跟着p1 
	 			p1=p1->next;
			 }
			 if(p0->num<=p1->num)//如果p0指向的学号小于p1指向的学号 
			 {
			 	if(head=p1)//如果p1作为头指针,那么p0需要作为新的头指针,顺次后延 
			 	head=p0;
			 	else//如果p1不是头指针,是中间的一个单元 
			 	p2->next=p0;
			 	p0->next=p1;//p2的末尾连着p0,p0的末尾连着p1 
			 }
			 else//如果p0指的学号大于等于p1的学号 
		{
			p1->next=p0;//那么p1的末尾连着p0,p0指向一个空的位置 
			p0->next=NULL;
		}
		n++;//成功插入这个学生的信息,学生数+1 
		return (head);//返回头指针 
		 }
		void print(struct student *head)//输出函数(传进去的参数是头指针) 
		{
			struct student *p;//由于只涉及到输出的问题,不需要增删,所以只需要用一个指针 
			printf("\nNow,These %d records are:\n",n);
			p=head;//让p作为头指针 
			if(head!=NULL)//如果头指针不是空的 
			do
			{
				printf("%s %5.1f\n",p->num,p->score);//那么就一次输出学生的学号,成绩 
				p=p->next;//让指向学生信息的指针依次往下跳 
			}while(p!=NULL);
		}

题目是C语言程序设计第五版学习辅导第九章内容

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值