C语言通过单链表的增删改查操作,实现对学生信息的管理
C语言通过单链表的增删改查操作,实现对学生信息的管理
一、问题分析
这道题要求运用单链表来实现对学生信息的管理。应该创建一个结构体,该结构体里存储一个学生所有信息,即学号和成绩,还应有一个指向下一个结点的指针来实现链表的连贯。增删改查:分别用一个子函数来实现,用主函数的一个switch函数来控制循环和结束。
创建一个链表:首先需要一个头结点,其数值域为空,指针域为head,用于定位和作为该链表的地址。笔者采用含头结点的尾插法创建链表。外部环境输入若干个学生的信息(要求按照学号从小到大的顺序输入),直到输入0时,结束输入。将第一个学生的信息存放在头结点的下一个结点,若下一个输入的值不为0则将下一个学生的信息存入下一个结点实现链表管理。
删除一个学生信息:外部环境输入一个学生的学号后,将从链表的头开始比较,若某一个结点的学号值小于输入的学号,则指向下一个结点继续进行比较,直到该链表的末尾。同时也需要考虑输入学号比第一个结点的学号值都小和链表里没有该学生信息的情况。
插入一个学生信息:外部环境输入一个学生的学号和成绩,将这些数据存入一个新创建的结点。从第一个结点开始比较新插入点的学号和该点的学号,若插入的学号更大,则与下一个结点的学号进行比较,直到该链表的末尾或者该点的学号大于插入的学号时,则在该点的前插入新增的学生信息,用链表插入的方式实现。同时需要考虑插入点的学号最小和链表内已存在该学生信息两种情况。
修改某一学生信息:外部环境输入一个学生的学号和成绩,从链表的第一个结点开始,将该结点的学号与新输入的学号进行比较,若新输入的学号更大,则与下一个结点的学号进行比较,直到两者学号相等时,将新输入的成绩值赋给该结点的成绩域。同时也要考虑学生表中没有该学号的学生的情况。
显示现在的学生表:用一个新定义的指针来进行定位,先将该指针指向头指针的下一个结点,显示该结点的数值域(运用printf函数来实现),并将新建指针指向下一个结点,直到结点为空(即链表的末尾)
二、代码实现
#include<stdio.h>
#include<malloc.h>
#include <stdlib.h>
#include <string.h>
#define LEN sizeof(struct student)
struct student*creat();
struct student*dele();
struct student*insert();
struct student*modify();
struct student*print()
struct student
{ long num ;
float score;
struct student *next;
};
int n;
int main()
{
int x;
struct student*head;
head=(struct student*)malloc(LEN);
head->next=NULL;
printf("请输入你想对链表进行什么操作\n");
printf("\"1\"创建一个链表, \"2\"删除一个学生信息, \"3\"插入一个学生信息, \"4\"修改某一学生信息, \"5\"打印学生表,\"0\"结束\n");
while(scanf("%d",&x)!=0)
{
switch(x)
{
case 1 :
head=creat(head);
break;
case 2 :
head=dele(head);
break;
case 3 :
head=insert(head);
break;
case 4 :
head=modify(head);
break;
case 5 :
head=print(head);
break;
default:
printf("Bye!!\n");
return 0;
}
printf("\"1\"创建一个链表, \"2\"删除一个学生信息, \"3\"插入一个学生信息, \"4\"修改某一学生信息, \"5\"打印学生表,\"0\"结束\n");
}
system("pause");
return 0;
}
struct student*creat(struct student*head) /*创建一个链表*/
{
struct student *p1,*p2;
int n=0;
printf("\n请按照学生学号顺序输入学生学号和成绩\n键入0结束输入\n"); /*区分中文英文的逗号*/
p1=p2=(struct student*)malloc(LEN);
scanf("%ld,%f",&p1->num,&p1->score);
printf("%5ld,%15f\n",p1->num,p1->score);
while(p1->num!=0)
{n=n+1;
if(n==1) head->next=p1;
else p2->next=p1;
p2=p1;
p1=(struct student*)malloc(LEN);
scanf("%ld,%f",&p1->num,&p1->score);
printf("%5ld,%15f\n",p1->num,p1->score);
}
printf("\n一共增加%d位学生。\n\n",n);
p2->next=NULL;
return head;
}
struct student*dele(struct student*head) /*删除一个学生信息*/
{
struct student *p1,*p2;
int num;
if(head->next==NULL)
{printf("这个学生表是空表!!\n");
return head;
}
printf("请输入需要删除的学生的学号\n");
scanf("%d",&num);
p1=(struct
student*)malloc(LEN);
p1=head->next;
while(num!=p1->num&&p1->next!=NULL)
{p2=p1;
p1=p1->next;
}
if(num==p1->num)
{if(p1==head->next)head->next=p1->next;
else p2->next=p1->next;
printf("删除成功。\n\n");
}
else printf("该学生表里没有学号为%d的学生的信息,请核对\n\n",num);
return head;
}
struct student*insert(struct student*head) /*插入一个学生信息*/
{
struct student *p1,*p2,*new_stu;
long num;
float score;
p1=head->next;
new_stu=(struct student*)malloc(LEN);
printf("请输入学生学号和成绩\n");
scanf("%ld,%f",&new_stu->num,&new_stu->score);
if(head->next==NULL)
{head->next=new_stu;
new_stu->next=NULL;
}
else {
while(p1->num<new_stu->num&&p1->next!=NULL)
{p2=p1;
p1=p1->next;
}
if(p1->num<new_stu->num&&p1->next==NULL)
{p1->next=new_stu;
new_stu->next=NULL;
}
else if(p1->num>new_stu->num)
{if(head->next==p1)head->next=new_stu;
else p2->next=new_stu;
new_stu->next=p1;
}
else if(p1->num==new_stu->num)
{printf("插入失败。\n\n");
return head;
}
}
printf("插入成功。\n\n");
return head;
}
struct student*modify(struct student*head) /*修改某一学生信息*/
{
struct student *p1;
long num;
float score;
p1=head->next;
printf("请输入学生学号和成绩\n");
scanf("%ld,%f",&num,&score);
while(num>p1->num&&p1!=NULL)
p1=p1->next;
if(num==p1->num)
{p1->score=score;
printf("修改成功。\n\n");
}
else printf("这名学生不在学生表中\n\n");
return head;
}
struct student*print(struct student*head) /*显示现在的学生表*/
{
struct student *p1;
p1=head->next;
printf("\t学号\t成绩\t\n");
while(p1!=NULL)
{
printf("\t%ld\t%f\t\n",p1->num,p1->score);
p1=p1->next;
}
return head;
}
三、结果截图
下一篇: MySQL的索引及索引优化