#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct student
{
int num;
char name[10];
int grade;
};
struct node
{
student date;
node *next;
};
//typedef struct node node; //把struct node 定义为 node
void add(node*header) {
student date;
printf("\n");
printf("\t\t\t ********************************\n");
printf("\t\t\t 请输入学生的学号,成绩,姓名\n");
printf("\t\t\t ");
scanf_s("%d%d", &date.num,&date.grade);
scanf_s("%s",date.name,10); //结构体中的字符串输入要有空间
printf("\n");
node*new_node;
new_node = (struct node*)malloc(sizeof(struct node));
new_node->date = date;
new_node->next = header->next; //头插法
header->next= new_node;
printf("\n");
printf("\n");
printf("\n");
}
void revise(node*header) {
int num;
int x=0;
node*pose_node= header->next;
node*front_node= header;
printf("\n");
printf("\t\t\t ********************************\n");
printf("\t\t\t 请输入要修改学生的学号:");
scanf_s("%d",&num);
if(pose_node==NULL){
printf("\t\t\t 对不起链表为空,无法修改\n");
return;
}
while(pose_node->date.num!=num)
{
front_node=pose_node; //定义目标节点前一个节点的意义
pose_node=front_node->next;
if(pose_node==NULL){
printf("\t\t\t 对不起没有找到目标学生\n");
return; //ruturn结束函数的用法
}
}
printf("\n");
printf("\n");
printf("\n");
printf("\t\t\t 需要修改的学生信息如下:\n");
printf("\t\t\t ********************************\n");
printf("\t\t\t 学号为%d,姓名为%s,成绩为%d\n",pose_node->date.num,pose_node->date.name,pose_node->date.grade);
printf("\t\t\t ********************************\n");
printf("\n");
printf("\t\t\t ********************************\n");
printf("\t\t\t 修改学号输入1\n");
printf("\t\t\t ********************************\n");
printf("\t\t\t 修改姓名输入2\n");
printf("\t\t\t ********************************\n");
printf("\t\t\t 修改成绩输入3\n");
printf("\t\t\t ********************************\n");
printf("\t\t\t 输入其他数字返回菜单\n");
printf("\t\t\t ********************************\n");
printf("\t\t\t 请输入:");
scanf("%d",&x);
printf("\n");
if(x==1){
printf("\t\t\t ********************************\n");
printf("\t\t\t 请输入修改后的学号:");
scanf("%d",&pose_node->date.num);
printf("\n");
printf("\t\t\t ********************************\n");
printf("\t\t\t 修改完成");
printf("\n");
}else if(x==2){
printf("\t\t\t ********************************\n");
printf("\t\t\t 请输入修改后的姓名:");
scanf("%s",pose_node->date.name);
printf("\n");
printf("\t\t\t ********************************\n");
printf("\t\t\t 修改完成");
printf("\n");
}else if(x==3){
printf("\t\t\t ********************************\n");
printf("\t\t\t 请输入修改后的成绩:");
scanf("%d",&pose_node->date.grade);
printf("\n");
printf("\t\t\t ********************************\n");
printf("\t\t\t 修改完成");
printf("\n");
}else
{
printf("\t\t\t ********************************\n");
printf("\t\t\t 已返回菜单");
printf("\t\t\t ********************************\n");
printf("\n");
}
printf("\n");
printf("\n");
printf("\n");
}
void delete_(node*header) {
int num;
node*pose_node= header->next;
node*front_node= header;
printf("\t\t\t ********************************\n");
printf("\t\t\t 请输入要删除学生的学号:");
scanf_s("%d",&num);
if(pose_node==NULL){
printf("\n");
printf("\t\t\t 对不起链表为空,无法删除\n");
return;
}
while(pose_node->date.num!=num)
{
front_node=pose_node; //定义目标节点前一个节点的意义
pose_node=front_node->next;
if(pose_node==NULL){
printf("\n");
printf("\t\t\t 对不起没有找到目标学生\n");
return; //ruturn结束函数的用法
}
}
front_node->next=pose_node->next; //防止断链
free(pose_node); //fron_node指向一个节点,它不能被认为就是这个节点,但是front_node->next就是这个节点的next
printf("\n");
printf("\t\t\t 删除完成");
printf("\n");
printf("\n");
printf("\n");
}
void find(node*header) {
int num;
node*pose_node= header->next;
node*front_node= header;
printf("\t\t\t ********************************\n");
printf("\t\t\t 请输入要查找学生的学号:");
scanf_s("%d",&num);
if(pose_node==NULL){
printf("\t\t\t 对不起链表为空,无法查找\n");
return;
}
while(pose_node->date.num!=num)
{
front_node=pose_node; //定义目标节点前一个节点的意义
pose_node=front_node->next;
if(pose_node==NULL){
printf("\t\t\t 对不起没有找到目标学生\n");
return; //ruturn结束函数的用法
}
}
printf("\n");
printf("\t\t\t 你所查找的学生信息如下:\n");
printf("\t\t\t ********************************\n");
printf("\t\t\t 学号为%d,姓名为%s,成绩为%d\n",pose_node->date.num,pose_node->date.name,pose_node->date.grade);
printf("\t\t\t ********************************\n");
printf("\n");
printf("\n");
printf("\n");
}
void range(node*header) {
node*first;
node*pend;
node temp;
char a[10];
first=header->next;
pend=NULL;
if(first=NULL){
printf("\t\t\t 对不起,链表为空,无法排序");
return;
}
while (first!=pend)
{
while (first->next!=pend)
{
if (first->date.num>first->next->date.num)
{
temp.date.num=first->date.num;
first->date.num=first->next->date.num;
first->next->date.num=temp.date.num;
temp.date.grade=first->date.grade;
first->date.grade=first->next->date.grade;
first->next->date.grade=temp.date.grade;
strcpy(a,first->date.name);
strcpy(first->date.name,first->next->date.name);
strcpy(first->next->date.name,a);
}
first=first->next;
}
pend=first;
first=header->next;
}
printf("\n");
printf("\t\t\t 排序完成\n");
printf("\n");printf("\n");printf("\n");
}
void count(node*header) {
node*pose_node= header->next;
node*front_node= header;
int count=0;
int i,j;
if(pose_node==NULL){
printf("\t\t\t 对不起链表为空,无法计数\n");
return;
}
while (pose_node)
{
front_node=pose_node; //计算节点数目
pose_node=front_node->next;
count++;
}
printf("\n");
printf("\t\t\t ********************************\n");
printf("\t\t\t 学生人数为%d\n",count);
printf("\t\t\t ********************************\n");
printf("\n");printf("\n");printf("\n");
}
void flip(node*header) { //自定义浏览函数
node*pMove = header->next;
if(pMove==NULL){
printf("\t\t\t 对不起链表为空,无法浏览\n");
return;
}
while (pMove) {
printf("\t\t\t ********************************\n");
printf("\t\t\t 学号为%d,姓名为%s,成绩为%d\n",pMove->date.num, pMove->date.name,pMove->date.grade);
printf("\t\t\t ********************************\n");
printf("\n");
pMove = pMove->next;
}
printf("\n");printf("\n");printf("\n");
}
int main() {
int n;
node*header=(struct node*)malloc(sizeof(struct node)); //表头也要动态内存分布
header->next=NULL; //初始化
header->date.grade=0;
header->date.num=0;
n = 0; //初始化n的值,为下一次进入菜单做准备
printf(" \n\n \n\n");
printf("\t\t ******************************************************\n\n");
printf("\t\t * 学生信息管理系统 *\n \n");
printf("\t\t ******************************************************\n\n");
printf("\t\t *********************系统功能菜单********************* \n");
printf("\t\t ---------------------- ---------------------- \n");
printf("\t\t ********************************************* \n");
printf("\t\t * 增加-----1 * * 修改-----2 * \n");
printf("\t\t ********************************************* \n");
printf("\t\t * 删除-----3 * * 查找-----4 * \n");
printf("\t\t ********************************************* \n");
printf("\t\t * 排序-----5 * * 统计-----6 * \n");
printf("\t\t ********************************************* \n");
printf("\t\t * 浏览-----7 * * 结束-----8 * \n");
printf("\t\t ********************** ********************** \n");
printf("\t\t ********************** ********************** \n");
printf("\t\t ----------------------- ---------------------- \n");
printf("\t\t\t\t 请选择菜单编号:");
while(n!=8){ //使用循环,保证多次进入菜单
scanf_s("%d",&n);
switch (n){
case 1:
add(header);
printf("\t\t\t\t 请选择菜单编号:");
break;
case 2:
revise(header);
printf("\t\t\t\t 请选择菜单编号:");
break;
case 3:
delete_(header);
printf("\t\t\t\t 请选择菜单编号:");
break;
case 4:
find(header);
printf("\t\t\t\t 请选择菜单编号:");
break;
case 5:
range(header);
printf("\t\t\t\t 请选择菜单编号:");
break;
case 6:
count(header);
printf("\t\t\t\t 请选择菜单编号:");
break;
case 7:
flip(header);
printf("\t\t\t\t 请选择菜单编号:");
break;
case 8:
printf("\n");
printf("\n");
printf("已经退出\n");
break;
default:
printf("\t\t\t\t 你的输入有误,请重新输入\n");
break;
}
}
return 0;
}
难点:
1菜单的多次使用
2对链表的熟悉(防止断链,对指针的理解
fron_node指向一个节点,它不能被认为就是这个节点,但是front_node->next就是这个节点的next)
3表头也要动态内存分配
4typedef struct node node; //把struct node 定义为 node
5scanf_s("%s",date.name,10); //结构体中的字符串输入要有空间
6ruturn结束函数的用法
7指针要初始化
8界面的美化