用单链表构建学生信息管理系统(一)

2020-06-29 11:44:49 浏览数 (1)

/*

2017年10月19日19:23:29

目的:自己去编写一个单链表并且对其进行打印、查找、插入、删除等

一些列操作。

*/

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#define LEN sizeof(struct student_node)

#define Max_studnet 100 //学生数量最大值,可根据情况调节

typedef struct student_node

{

long num;

char name[20]; //姓名长度不超过20个字符

float score;

struct student_node *next;

} LinkList; //自定义链表

int main()

{

LinkList *LinkListCreat(); //创建链表,返回表头指针

void print(LinkList *P); //函数声明,打印学生信息

void sort(LinkList *p); //学生成绩排序函数

LinkList *LocatebyID(LinkList *p, long n); //按学号查找节点

LinkList *LocatebyNum(LinkList *p, int n); //按序号查找节点

LinkList *LocatebyVal(LinkList *p, char name[]); //按姓名查找学生

int Insert(LinkList *p, int n, long num1, char name1[], float score1); //在第n个位置插入学生信息,创建新节点

int Delete(LinkList *p, int n); //删除第n个学生的信息

char x;

long id; //学号

LinkList *p, *q, *t;

//插入信息所用到的变量

int n1; //插入学生信息位置

long num1;

char name1[20];

float score1;

//创建链表

p = LinkListCreat(); //创建链表,p指向表头节点

q = p->next; //q指向表头节点后的第一个节点,即序号为1的节点

printf("学生管理系统使用方法:n");

printf("功能 (p)t输出学生信息n");

printf("功能 (s)t对按分数的大小对学生进行排序n");

printf("功能 (l)t按学号查找学生信息n");

printf("功能 (i)t在某位置插入学生信息n");

printf("功能 (d)t删除某学生的信息n");

printf("功能 (q)t退出n");

while(1)

{

printf("请输入功能选项:t");

getchar(); //过滤回车符

scanf("%c", &x);

//过滤回车符,即如果输入了回车符,则继续提示用户输入

if(x == 'n')

{

continue;

}

switch(x)

{

//打印输出功能

//可以使用打印函数替换本部分程序

case 'p':

while(q) //q为序号1的节点

{

printf("%ldt%st%fn",q->num, q->name, q->score);

q = q->next; //q指向下一个节点

}

q = p->next; //命令执行完成后,指针指向原位置

break;

//对学生成绩进行排序并输出

case 's':

sort(q); //对学生成绩排序并且输出

q = p->next; //命令执行完成后,指针指向原位置

break;

//按学号查询学生信息

case 'l':

printf("请输入学生学号:");

scanf("%ld", &id);

t = LocatebyID(q, id);

q = p->next; //命令执行完成后,指针指向原位置

if(t == NULL)

{

printf("错误!没有这个学生n");

}

else

printf("%ldt%st%fn",t->num, t->name, t->score);

break;

//在指定位置插入学生信息

case 'i':

printf("请输入插入位置:t");

scanf("%d", &n1);

printf("请输入学号、姓名、分数:n");

printf("学号:t");

scanf("%ld", &num1);

printf("姓名:t");

getchar();

gets(name1);

printf("成绩:t");

scanf("%f", &score1);

//调用插入学生信息函数

Insert(q, n1, num1, name1, score1);

q = p->next; //命令执行完成后指针指向原来位置

printf("插入该学生信息后打印学生信息:n");

print(q);

q = p->next; //命令执行完成后指针指向原来位置

break;

case 'd':

printf("请输入需要删除的学生序号:");

scanf("%d", &n1);

Delete(q, n1);

q = p->next; //命令执行完成后指针指向原位置

printf("删除操作后打印学生信息:n");

print(q);

q = p->next; //命令执行完成后指针指向原位置

break;

case 'q':

return 0;

break;

default:

printf("功能输入错误!n");

break;

}

}

return 0;

}

LinkList *LinkListCreat()

{

LinkList *p, *p1, *p2;

long num1;

char name1[20];

float score1;

//创建表头节点

p = (LinkList *)malloc(LEN);

//赋初始值

p->num = 0;

p->name[20] = "nothing";

p->score = 0;

p->next = NULL;

p1 = p; //p1指向表头节点

printf("请输入学生学号、姓名、分数:n");

printf("注意:学号为0代表输入结束n");

printf("学号:t");

scanf("%ld", &num1);

printf("姓名:t");

getchar(); //过滤回车符

gets(name1);

printf("成绩:t");

scanf("%f", &score1);

for( ; num1 != 0; ) //学号为0则结束

{

p2 = (LinkList *)malloc(LEN);

p2->num = num1;

strcpy(p2->name, name1);

p2->score = score1;

p2->next = NULL;

p1->next = p2;

p1 = p2;

printf("学号:t");

scanf("%ld", &num1);

if(num1 != 0)

{

printf("姓名:t");

getchar();

gets(name1);

printf("成绩:t");

scanf("%f", &score1);

}

}

return p;

}

//打印指针,记得执行完成后要将指针指向原位置即序号1元素

void print(LinkList *p)

{

while(p)

{

printf("%ldt%st%fn",p->num, p->name, p->score);

p = p->next;

}

}

//排序函数定义

//选择排序法,成绩从高到低排序

void sort(LinkList *p)

{

int i, j, sum = 0; //sum 用来保存学生个数

float temp;

LinkList *q;

float array[Max_studnet];

int k;

//统计学生个数

q = p; //保护现场,保证不改变p的指向

while(q != NULL)

{

sum ;

q = q->next;

}

//将学生成绩放入数组

q = p; //q再次指向序号1节点

for(i = 0; i < sum; i )

{

array[i] = q->score; //将学生成绩放入数组

q = q->next;

}

//对学生成绩进行排序

for(i = 0; i < sum - 1; i )

{

k = i;

for(j = i 1; j < sum; j )

{

if(array[k] < array[j])

{

k = j;

}

}

if(k != i)

{

temp = array[k];

array[k] = array[i];

array[i] = temp;

}

}

//按顺序输出学生成绩

for(i = 0; i < sum; i )

{

printf("%ft", array[i]);

if( (i 1) % 5 == 0 )

printf("n");

}

printf("n");

}

//通过学号查询学生信息

LinkList *LocatebyID(LinkList *p, long n)

{

LinkList *q;

q = p;

while(q)

{

if(n == q->num)

{

return q;

}

q = q->next;

}

return NULL;

}

//定义按序号查找节点函数

LinkList *LocatebyNum(LinkList *p, int n)

{

int i = 1;

LinkList *q;

q = p;

while(q)

{

if(n == i)

{

return q;

}

i ;

q = q->next;

}

return NULL;

}

//定义插入函数

int Insert(LinkList *p, int n, long num1, char name1[], float score1)

{

LinkList *p1, *p2;

p1 = LocatebyNum(p, n - 1);

if(p1 == NULL)

{

printf("错误!不存在此节点!n");

return -1;

}

p2 = (LinkList *)malloc(LEN);

p2->num = num1;

strcpy(p2->name, name1);

p2->score = score1;

p2->next = p1->next;

p1->next = p2;

return 0;

}

//定义删除函数

int Delete(LinkList *p, int n)

{

LinkList *p1, *p2;

p1 = LocatebyNum(p, n - 1);

if(p1 == NULL)

{

printf("错误!不存在此节点!n");

return -1;

}

p2 = p1->next;

p1->next = p2->next;

free(p2);

return 0;

}

/*

在Code::Blocks中的输出结果为:

请输入学生学号、姓名、分数:

注意:学号为0代表输入结束

学号: 609

姓名: han

成绩: 86

学号: 611

姓名: xie

成绩: 58

学号: 0

学生管理系统使用方法:

功能 (p) 输出学生信息

功能 (s) 对按分数的大小对学生进行排序

功能 (l) 按学号查找学生信息

功能 (i) 在某位置插入学生信息

功能 (d) 删除某学生的信息

功能 (q) 退出

请输入功能选项: p

609 han 86.000000

611 xie 58.000000

请输入功能选项: s

86.000000 58.000000

请输入功能选项: l

请输入学生学号:609

609 han 86.000000

请输入功能选项: i

请输入插入位置: 2

请输入学号、姓名、分数:

学号: 610

姓名: li

成绩: 98

插入该学生信息后打印学生信息:

609 han 86.000000

610 li 98.000000

611 xie 58.000000

请输入功能选项: d

请输入需要删除的学生序号:3

删除操作后打印学生信息:

609 han 86.000000

610 li 98.000000

请输入功能选项: q

Process returned 0 (0x0) execution time : 77.873 s

Press any key to continue.

2017年10月20日20:02:01

心得:功夫不负有心人,终于独立编写出了一个像样的程序,基本满足了自己的想法。

但问题仍然十分突出,例如错误的输入会导致莫名其妙的结果,这是本程序的bug,到此

仅仅是一个开始,而非一个结束,继续学习新的内容,复习旧的内容,并时常编写一些

有想法的程序去检验自己的学习成果。加油。

*/

0 人点赞