跟昨天一样——学生成绩-链表存储
今天做成了一个可随时更改的系统
新内容:
- 改进了查找的将要删除节点的方法(之前是按节点序号删除的,这次改进为查找学号删除)
- 比昨天多增加了插入节点功能
- 能进行反复插入和删除读写
#include<stdio.h>
struct stu_result
{
int num;
float score;
struct stu_result *next;
};
struct stu_result *build();//创建链表
void prinf(struct stu_result *head);//输出链表
struct stu_result *delet(struct stu_result *head,int a);//链表的节点删除
struct stu_result *insert(struct stu_result *head,struct stu_result *stu_new);//链表的节点插入
int main()
{
char x;//字符变量x是来判断是否增删链表节点的
int num,n=0;//i为需要删除的第几个链表元素
struct stu_result *stu,stu_new[100];
stu=build();
printf("\n\n");
prinf(stu);
while(1)
{
fflush(stdin);//清空缓存区,以免影响到x的判断
printf("您需要删除还是添加学生成绩?删除输入D,添加输入A,结束输入e!");
scanf("%c",&x);
if(x=='e')
{
printf("结束修改!");
break;
}
else if(x=='D')
{
printf("请输学号!:");
scanf("%d",&num);
stu=delet(stu,num);
printf("\n");
prinf(stu);
}
else if(x=='A')
{
n++;
printf("请输入学号:");
scanf("%d",&stu_new[n].num);
printf("请输入成绩:");
scanf("%f",&stu_new[n].score);
stu=insert(stu,&stu_new[n]);
prinf(stu);
}
}
}
struct stu_result *build()
{
int n;//指创建到第几个节点
struct stu_result student[100],*head,*p1,*p2;
/*我利用数组来建立链表,也可以用malloc函数来建立链表
p1和p2是方便用来指向新创建的节点的*/
![学生链表系统.jpg](https://img.haomeiwen.com/i9896518/d2a9d54d32f8ca6b.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
p1=p2=&student[0];//p1,p2先初始化指向第一个节点
head=NULL;//初始化
printf("请输入学号(0结束):") ;
scanf("%d",&p1->num);
for(n=0;p1->num!=0;)//判断是否输入0,是否应该创建下一个节点
{
n=n+1;
if(n==1)//进行首次的节点创建(之后就用不着了)
{
head=p1;//head指向第一个节点
}
else//再次的指向新创建的节点
{
p2->next=p1;
}
printf("请输入分数:");
scanf("%f",&p1->score);
p2=p1;//(首次节点创建时用不着),从第二次后开始,p2与p1同步指向新节点
p1=&student[n];//开辟新节点
printf("请输入学号(0结束):");
scanf("%d",&p1->num);
}
p2->next=NULL;//结束最后一个节点,指向NULL
return head;//返回链表
}
void prinf(struct stu_result *head)
{
printf("\n");
while(head!=NULL)
{
printf("学号%d\n",head->num);
printf("分数为%f\n",head->score);
head=head->next;
printf("\n");
}
}
struct stu_result *delet(struct stu_result *head,int i)
{
struct stu_result *newstu;//新链表
struct stu_result *p1,*p2;//用来替换初始的head,方便返回原链表
p1=p2=head;
if(head==NULL)
{
printf("链表是空的,无法删除!");
return head;
}
else if(i==head->num)
{
p1=p1->next;
newstu=p1;
return newstu;/************************
因为第一个节点改变了(最初的sut链表中的head改变)
所以他的头地址必须更新,返回一个新的头地址链表
***********************/
}
else
{
while(i!=p1->num)
{
if(p1->next==NULL)
{
printf("\n\n链表中没有这位同学的学号,无法删除!");
return head;
}
p2=p1;
p1=p1->next;
}
p2->next=p2->next->next;
return head;
/**********************************
第一个节点没有改变(head不变),
根据链表的性质,指向下一个节点的地址。
所以返回原来的链表即可,无需返回新的链表
**********************************/
}
}
struct stu_result *insert(struct stu_result *head,struct stu_result *stu_new)
{
struct stu_result *p1,*p2;
p1=p2=head;
if(p1==NULL)//如果是空链表
{
head=stu_new;
stu_new->next=NULL;
}
else
{
while(stu_new->num>p1->num&&p1->next!=NULL)
{
p2=p1;
p1=p1->next;
}
if(stu_new->num<=p1->num)//链表末尾前如何插入
{
if(p1==head)//如果处于第一个节点插入
{
head=stu_new;
stu_new->next=p1;
}
else//在第一个和最后一个之间插入
{
p2->next=stu_new;
stu_new->next=p1;
}
}
else//链表末尾插入
{
p1->next=stu_new;
stu_new->next=NULL;
}
}
return head;
}
学生链表系统.jpg
网友评论