单链表实现学生成绩统计每个学生包含姓名、性别、学号、成绩的输入,至少输入10个学生,并将成绩按照男女分离形成两个单链表,并对两个单链表进行排序。
C代码运行结果如下:
代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
typedef struct _Student
{
int id; //学号
char name[20];//姓名
char sex; //性别
int score; //成绩
struct _Student* next;
}Student;
//初始化链表头
Student* initList(Student* list)
{
list = (Student*)malloc(sizeof(Student));
list->next = 0;
return list;
}
//头插法创建链表
void createList(Student* list)
{
int i, n;
Student* t,*p;
p = list;
printf("请输入需要插入的学生数量:");
scanf("%d", &n);
for (i = 0; i < n; i++)
{
t = (Student*)malloc(sizeof(Student));
t->next = 0;
printf("请输入第%d个学生的学号:", i + 1);
scanf("%d", &t->id);
printf("请输入第%d个学生的姓名:", i + 1);
scanf("%s", t->name);
getchar();//吸收回车符
printf("请输入第%d个学生的性别(F/M):", i + 1);
scanf("%c", &t->sex);
printf("请输入第%d个学生的成绩:", i + 1);
scanf("%d", &t->score);
//插入头插法插入链表
p->next = t;
p = t;
}
}
//遍历输出学生信息
void showList(Student* list)
{
Student* p;
if (list == 0) return;
p = list->next;
while (p)
{
printf("%8d %20s %c %3d\n", p->id, p->name, p->sex, p->score);
p = p->next;
}
}
//分隔链表
void splitList(Student* plistA, Student* plistB)
{
Student* pre = plistA;
Student* p = pre->next;
Student* pb = plistB;
while (p)
{
if (p->sex == 'M')
{
pre->next = p->next; //把p从listA中删除
//把p插入listB
p->next = 0;
pb->next = p;
pb = p;
//重置p,继续循环
p = pre->next;
}
else
{
pre = p;
p = p->next;
}
}
}
//根据成绩排序
void sortById(Student* L)
{
Student* p, * tail, * q;
tail = NULL;
while ((L->next->next) != tail)
{
p = L;
q = L->next;
while (q->next != tail)
{
if (q->score > q->next->score) //升序排列 /降序
{
p->next = q->next;
q->next = q->next->next;
p->next->next = q;
q = p->next;
}
q = q->next;
p = p->next;
}
tail = q;
}
}
int main()
{
Student* listA = 0;
Student* listB = 0;
listA = initList(listA);
listB = initList(listB);
//输入数据并创建链表
createList(listA);
showList(listA);
//分成两个链表
splitList(listA, listB);
printf("分隔后的女生链表为:\n");
showList(listA);
printf("分隔后的男生链表为:\n");
showList(listB);
//排序
sortById(listA);
sortById(listB);
printf("排序后的女生链表为:\n");
showList(listA);
printf("排序后的男生链表为:\n");
showList(listB);
return 0;
}
参考一下
# include <stdio.h>
# include <conio.h>
# include <malloc.h>
# include <stdlib.h>
struct Node
{
int num;
int age;
char name[30];
char sex[5];
int sroce;
struct Node *next;
};
Node *head;
Node *Load() //载入文件中的数据到结构体中
{
FILE *fp;
Node *cur,*p,*q;
cur = NULL;
fp = fopen("Student","r"); //以"r"形式打开student的文件
if(fp == NULL) //如果文件不存在
{
fp = fopen("Student","w"); //创立一个student文件
fclose(fp); //关闭文件
return cur; //返回链表中,存入head
}
p=(struct Node*)malloc(sizeof(struct Node)); //如果存在
if(fread(p,sizeof(struct Node),1,fp) != 1) //判断文件中的数据 是否只有1个
return cur; //是就返回
cur = p;
while(!feof(fp)) //否则就开始从文件中读数据
{
q = p;
p = (struct Node *)malloc(sizeof(struct Node));
fread(p,sizeof(struct Node),1,fp);
q -> next = p;
}
q -> next = NULL;
free(p); //释放指针p所指向的内存空间
fclose(fp);
return cur; //返回链表中,存入head
}
void Interface() //主界面函数
{
system( "cls" ); //清屏函数
printf("\n\n\n");
printf("\t-----------------------------------------------------\n");
printf("\t-----------------------------------------------------\n");
printf("\t|| ||\n");
printf("\t|| 首页 ||\n");
printf("\t|| ||\n");
printf("\t-----------------------------------------------------\n");
printf("\t-----------------------------------------------------\n");
printf("\t|| ||\n");
printf("\t|| ||\n");
printf("\t|| ◆1.输入 ||\n");
printf("\t|| ◆2.查询 ||\n");
printf("\t|| ◆3.显示 ||\n");
printf("\t|| ◆4.删除 ||\n");
printf("\t|| ◆5.修改 ||\n");
printf("\t|| ◆0.退出 ||\n");
printf("\t|| ||\n");
printf("\t|| ||\n");
printf("\t-----------------------------------------------------\n");
printf("\t-----------------------------------------------------\n");
return ;
}
void Add_Data() //输入学生信息函数
{
Node *p,*q;
Node *cur;
char flag = '0';
cur = (struct Node *)malloc(sizeof(struct Node)); //创建新结点
while(flag == '0') //输入学生信息
{
q = p = head;
cur ->next = NULL;
printf("请输入姓名:");
scanf("%s",&cur -> name);
printf("请输入学号:");
scanf("%d",&cur -> num);
printf("请输入年龄 :");
scanf("%d",&cur -> age);
printf("请输入性别 :");
scanf("%s",&cur -> sex);
printf("请输入成绩 :");
scanf("%d",&cur -> sroce);
fflush(stdin); //用来清空输入缓存,以便不影响后面输入的东西
if(head == NULL)head = cur; //如果输入的节点是头一个,就把头结点head等于cur
else //否则在头结点后面加入结点
{
while(p -> num < cur -> num && p -> next != NULL) //按学号建立链表
{
q = p; //P节点
p = p -> next; //P后一接点
}
if(p -> num > cur -> num) //找到head表中的学号大于新建学生的学号,插入学生信息
{
if(p == head) //如果为头结点,前插
{
cur -> next = head;
head = cur;
}
else
{
q -> next = cur;
cur -> next = p;
}
}
else //找不到比新建学生更大的学号,放在链表最好面
p -> next = cur;
}
cur = (struct Node *)malloc(sizeof(struct Node)); //又创建新结点,为下次输入准备
printf("输入结束,是否继续输入,按 0 键继续,否者退出.\n");
flag = getch(); //0就继续输入,其他键就返回主界面
fflush(stdin); //清除缓冲区的数据
}
free(cur);
return ;
}
void Find_Data() //按学号查找学生信息
{
Node *p;
int num;
char flag = '0';
bool mark;
while(flag == '0')
{
printf("请输入要查找的学生的学号: ");
scanf("%d",&num);
fflush(stdin);
mark = false; //标记是否找到学生
p = head; //将头结点head赋值与p
if(head == NULL) //如果链表中头结点为空,则查询错误
{
printf("查询失败.\n");
printf("不存在此学生信息.\n");
return ;
}
else //否则开始查询
{
while(p != NULL)
{
if(p -> num == num) //找到学号为num的学生就输出
{
printf("你要查找的学生信息如下:\n");
printf("学号 :%d\n",p -> num);
printf("名字 :%s\n",p -> name);
printf("性别 :%s\n",p -> sex);
printf("年龄 :%d\n",p -> age);
printf("成绩 :%d\n",p -> sroce);
mark = true;
break;
}
else
p = p -> next;
}
}
if(!mark) //没找到学生与num匹配的学生
{
printf("查询失败.\n");
printf("不存在此学生信息.\n");
return ;
}
printf("查找结束,是否继续查找,按 0 键继续,否者退出.\n");
flag = getch();
fflush(stdin);
}
return ;
}
void Show_Data() //显示学生信息
{
Node *p;
p = head;
char flag;
while(p != NULL)
{
printf("你要查找的学生信息如下:\n");
printf("学号 :%d\n",p -> num);
printf("名字 :%s\n",p -> name);
printf("性别 :%s\n",p -> sex);
printf("年龄 :%d\n",p -> age);
printf("成绩 :%d\n",p -> sroce);
p = p -> next;
}
printf("输出结束,请按任意键继续.\n");
flag = getch();
fflush(stdin);
return ;
}
void Delete_Data() //按学号删除学生信息
{
Node *p,*q,*cur;
int num;
char flag = '0';
bool mark;
while(flag == '0')
{
printf("请输入要删除的学生的学号: ");
scanf("%d",&num);
fflush(stdin);
mark = false; //标记是否找到学生
p = q = head; //将头结点head赋值与p
if(head == NULL) //如果链表中头结点为空,则查询错误
{
printf("删除失败.\n");
printf("不存在此学生信息.\n");
return ;
}
else //否则开始查询
{
while(p != NULL)
{
if(p -> num == num) //找到学号为num的学生就输出
{
if(head == p)
head = p -> next;
else
q -> next = p -> next;
mark = true;
break;
}
else
{
q = p;
p = p -> next;
}
}
}
if(!mark) //没找到学生与num匹配的学生
{
printf("删除失败.\n");
printf("不存在学生信息.\n");
return ;
}
printf("删除结束,按 0 键继续,否者退出.\n");
flag = getch();
fflush(stdin);
}
return ;
}
void Update_date() //修改学生信息
{
Node *p;
int num;
char flag = '0';
bool mark;
while(flag == '0')
{
printf("请输入要修改的学生的学号: ");
scanf("%d",&num);
fflush(stdin);
mark = false; //标记是否找到学生
p = head; //将头结点head赋值与p
if(head == NULL) //如果链表中头结点为空,则查询错误
{
printf("修改失败.\n");
printf("不存在此学生信息.\n");
return ;
}
else //否则开始查询
{
while(p != NULL)
{
if(p -> num == num) //找到学号为num的学生就输出
{
printf("请输入姓名:");
scanf("%s",&p -> name);
printf("请输入学号:");
scanf("%d",&p -> num);
printf("请输入年龄 :");
scanf("%d",&p -> age);
printf("请输入性别 :");
scanf("%s",&p -> sex);
printf("请输入成绩 :");
scanf("%d",&p -> sroce);
fflush(stdin); //用来清空输入缓存,以便不影响后面输入的东西
mark = true;
break;
}
else
p = p -> next;
}
}
if(!mark) //没找到学生与num匹配的学生
{
printf("修改失败.\n");
printf("不存在此学生信息.\n");
return ;
}
printf("修改结束,按 0 键继续,否者退出.\n");
flag = getch();
fflush(stdin);
}
return ;
}
void Solve_Data() //将处理后的链表中的信息存进文件
{
FILE *fp;
fp = fopen("Student","w"); //以"w"形式打开student文件
while(head != NULL)
{
fwrite(head,sizeof(struct Node),1,fp); //写进student文件
head = head -> next;
}
fclose(fp);
return ;
}
void List() //菜单选择函数
{
char x;
bool flag = true;
while(flag)
{
Interface(); //菜单函数
x = getch();
system( "cls" );
fflush(stdin);
switch(x)
{
case '1':
Add_Data();
break;
case '2':
Find_Data();
break;
case '3':
Show_Data();
break;
case '4':
Delete_Data();
break;
case '5':
Update_date();
break;
default:
Solve_Data();
flag=false;
break;
}
}
return ;
}
int main()
{
head = Load();
List();
return 0;
}
直接控制台运行查看结果,望采纳
// 链表
const LinkList = function() {
this.head = null;
this.length = 0;
// 辅助类,创建节点
const Node = function(element) {
this.element = element;
this.next = null; //因为next用来存放对象,null是一个空的对象,因此这里使用空很合适
};
//在链表末尾添加元素
this.__proto__.append = function(element) {
const node = new Node(element);
if (this.head === null) {
this.head = node;
} else {
// 拿一个变量接收找到的最后一个节点,将添加的元素添加到最后一个节点的next属性
let current = this.head;
while (current.next) {
current = current.next;
}
current.next = node;
}
this.length++;
};
// 获取链表的头
this.__proto__.getHead = function() {
return this.head;
};
//得到链表的长度
this.__proto__.size = function() {
return this.length;
};
// 往链表指定位置插入元素(下标位置position从0开始)
this.__proto__.insert = function(position, element) {
let node = new Node(element);
// 插入位置不能越界
if (position > -1 && position <= this.length) {
// 在开头插入元素,相当于交换(插入的node和head两个数)
if (position == 0) {
let current = this.head;
this.head = node;
this.head.next = current;
} else if (position == this.length) {
//在末尾的位置插入
this.append(element);
// 在append方法中新建了一个node,所以将这个作用域中的node赋值为null,释放内存
node = null;
// append方法中执行了this.length++
this.length--;
} else {
// previous插入坐标前一个节点 current当前插入坐标的节点
let previous = null;
let current = this.head;
let index = 0;
while (index < position) {
previous = current;
current = current.next;
index++;
}
previous.next = node;
node.next = current;
}
this.length++;
return true;
} else {
// return new Error("插入的下标位置越界了,不能这样");
return false;
}
};
//检查链表是否为空
this.__proto__.isEmpty = function() {
return this.length === 0;
};
//传入要删除某个位置下标的元素
this.__proto__.removeAt = function(position) {
// 越界问题
if (position > -1 && position < this.length) {
let current = this.head;
//删除链表第一个元素
if (position === 0) {
this.head = current.next;
} else {
//while循环退出条件是,查找到链表的index下标位置为position时,进行删除操作
let index = 0;
let previous = null;
// 查询
while (index < position) {
previous = current;
current = current.next;
index++;
}
// 当index == position时,删除
previous.next = current.next;
}
this.length--;
return current;
} else {
return false;
}
};
//获取指定element的下标position
this.__proto__.indexOf = function(element) {
let index = 0;
let current = this.head;
while (current) {
if (current.element == element) {
return index;
}
current = current.next;
index++;
}
return -1;
};
// 删除指定元素
this.__proto__.remove = function(element) {
return this.removeAt(this.indexOf(element));
};
// 更新指定position下标的节点
this.__proto__.update = function(position, element) {
if (this.get(position)) {
this.get(position).element = element;
return true;
}
return false;
};
// 获取指定position下标的节点
this.__proto__.get = function(position) {
// 越界判断
if (position > -1 && position < this.length) {
let current = this.head;
let index = 0;
while (index < position) {
current = current.next;
index++;
}
return current;
} else {
return false;
}
};
// 删除链表最后一个节点
this.__proto__.delete = function() {
this.removeAt(this.length - 1);
};
// 以数组的形式输出链表所有的值
this.__proto__.toArray = function() {
return (function reversePrint(head) {
if (head) {
if (head.next) {
return [...reversePrint(head.next), head.element]
}
return [head.element]
}
return []
})(this.head);
}
};
// 快排
Array.prototype.quickSort = function() {
// 交叉替换辅助函数
const swap = function(array, index1, index2) {
let arrCopy = array[index2];
array[index2] = array[index1];
array[index1] = arrCopy;
};
// 递归辅助函数
function quickSortRec(array) {
if (array.length === 1) {
return array;
}
const mid = array[Math.floor(array.length / 2)];
let leftIndex = 0;
let rightIndex = array.length - 1;
while (leftIndex < rightIndex) {
while (array[leftIndex].score < mid.score && leftIndex < rightIndex) {
leftIndex++;
}
while (array[rightIndex].score > mid.score && leftIndex < rightIndex) {
rightIndex--;
}
swap(array, leftIndex, rightIndex);
leftIndex++;
rightIndex--;
}
return quickSortRec(array.slice(0, Math.floor(array.length / 2))).concat(
quickSortRec(array.slice(Math.floor(array.length / 2), array.length))
);
}
return quickSortRec(this);
};
// 学生类
class Student {
constructor(name, sex, studentId, score) {
this.name = name;
this.sex = sex;
this.studentId = studentId;
this.score = score;
}
}
class Main {
constructor() {
// 男生组链表
this.maleLinkList = new LinkList();
// 女生组链表
this.femaleLinkList = new LinkList();
}
// 录入学生
entry(student) {
student.sex === 'male' ? this.maleLinkList.append(student) : this.femaleLinkList.append(student);
}
result() {
console.log(this.maleLinkList.toArray().quickSort());
console.log(this.femaleLinkList.toArray().quickSort());
}
}
const main = new Main();
let i = 0;
while (i < 10) {
main.entry(new Student(i, i % 2 === 0 ? "male" : "female", i, i));
i++;
}
main.result();
/*
输出结果
[
Student { name: 0, sex: 'male', studentId: 0, score: 0 },
Student { name: 2, sex: 'male', studentId: 2, score: 2 },
Student { name: 4, sex: 'male', studentId: 4, score: 4 },
Student { name: 6, sex: 'male', studentId: 6, score: 6 },
Student { name: 8, sex: 'male', studentId: 8, score: 8 }
]
[
Student { name: 1, sex: 'female', studentId: 1, score: 1 },
Student { name: 3, sex: 'female', studentId: 3, score: 3 },
Student { name: 5, sex: 'female', studentId: 5, score: 5 },
Student { name: 7, sex: 'female', studentId: 7, score: 7 },
Student { name: 9, sex: 'female', studentId: 9, score: 9 }
]
*/
大一写的,改一改应该有用
https://download.csdn.net/download/qq_40331154/10809793?spm=1001.2014.3001.5503