(一)学生成绩排名
先采用选择法,将学生成绩从高到低进行排序,再输入一个学生的成绩,将此成绩按照排序规律插入已排好序的学生成绩数组,最后将排好序的成绩单进行反序存放。
1. 定义一个数组a[11],用以存放学生的成绩。
2. 从键盘输入10个学生成绩。
3. 采用选择法,将学生成绩按照从高到低进行排序。
4. 再输入一个学生的成绩,将此成绩按照排序规律插入原学生成绩数组。
5. 将排好序的成绩单进行反序存放,即原来是从高到低,现在改为从低到高排列。
将以上每一步骤的结果均打印输出,验证程序是否正确实现题目要求。
#include <stdio.h>
void Descend(int a[11]) {
int i, j, Max, temp;
for(i = 1; i <= 9; i++) {
Max = i;
for(j = i + 1; j <= 10; j++)
if(a[j] > a[Max])
Max = j;
temp = a[Max];
a[Max] = a[i];
a[i] = temp;
}
}
void Insert(int a[11], int add) {
int i = 1;
while(i <= 10 && add <= a[i]) {
a[i-1] = a[i];
i++;
}
a[i-1] = add;
}
void Ascend(int a[11]) {
int i, M;
for(i = 0; i < 5; i++) {
M = a[i];
a[i] = a[10-i];
a[10-i] = M;
}
}
void Print(int a[11]) {
for(int i = 1; i <= 10; i++)
printf("%d ", a[i]);
printf("\n");
}
void Printpro(int a[11]) {
for(int i = 0; i <= 10; i++)
printf("%d ", a[i]);
printf("\n");
}
int main() {
int a[11];
int i, add;
printf("Input the grades of ten students:\n");
for(i = 1; i <= 10; i++)
scanf("%d", &a[i]);
Descend(a);
printf("\nThe descending order is:\n");
Print(a);
printf("\nInput the grade you want to add:");
scanf("%d", &add);
Insert(a, add);
printf("\nNow the sequence is:\n");
Printpro(a);
Ascend(a);
printf("\nAnd,the reverse order is:\n");
Printpro(a);
return 0;
}
(二) 根据条件进行学生成绩排名
在函数中进行 10个学生成绩从高到低排名, 再改进函数, 进行 n个学生成绩从高到低排名, 排名方式根据函数的style参数进行,如style为‘a’按升序排,style为 ’ d ’ 按降序排( a:ascending 升,d:descending 降)。
编写多个不同函数,使之能实现不同的排序算法(3种以上),再编写一个通用输出函数,(要求用函数指针做参数)能分别打印不同排序算法的结果。
1. 在函数中进行10个学生成绩从高到低排名 sort(int a[10])
2. 改进第一步的函数为sort(int a[], int n)
,进行n个学生成绩从高到低排名
3. 改进第二步的函数为sort(int a[], int n, char style)
, 将n个学生成绩从高到低排名,排名方式根据sort()函数的style参数进行,如style为‘a’按升序排,style为’d’按降序排。(a:ascending 升,d:descending 降)
4. 编写4个排序函数,实现4种不同的排序算法(用冒泡法进行升序排序,用冒泡法进行降序排序,选择法进行升序排序,选择法进行降序排序等),函数返回指向排好序的数组的指针。
5. 编写通用输出函数 show(int *(* fun)(a[ ], int n))
,其中a[]为成绩数组,n为数组元素个数。
6. 编写主函数调用以上函数。
#include <stdio.h>
#define N 30
int *Bubble_ascending(int a[], int n) { //冒泡法升序
int *p;
int i, j, temp;
for(i = 0; i < n - 1; i++)
for(j = i + 1; j < n; j++) {
if(a[i] > a[j]) {
temp = a[j];
a[j] = a[i];
a[i] = temp;
}
}
p = a;
return p;
}
int *Bubble_descending(int a[], int n) { //冒泡法降序
int *p;
int i, j, temp;
for(i = 0; i < n - 1; i++)
for(j = i + 1; j < n; j++) {
if(a[i] < a[j]) {
temp = a[j];
a[j] = a[i];
a[i] = temp;
}
}
p = a;
return p;
}
int *Select_ascending(int a[], int n) { //选择法升序
int *p;
int i, j, temp, min;
for(i = 0; i < n - 1; i++) {
min = i;
for(j = i + 1; j < n; j++)
if(a[j] < a[min])
min = j;
temp = a[min];
a[min] = a[i];
a[i] = temp;
}
p = a;
return p;
}
int *Select_descending(int a[], int n) { //选择法降序
int *p;
int i, j, temp, max;
for(i = 0; i < n - 1; i++) {
max = i;
for(j = i + 1; j < n; j++)
if(a[j] > a[max])
max = j;
temp = a[max];
a[max] = a[i];
a[i] = temp;
}
p = a;
return p;
}
int *fun1(int a[], int n) {
int *p, *q;
p = &a[0];
q = p; //指针q指向数组的首地址
for(; p < q + n; p++) //用指针p输出数组
printf("%d ", *p);
return q;
}
void show(int *(*fun)(int a[], int n), int a[], int n) {
fun(a, n);
printf("\n");
}
void SORT(int a[], int n, char style) {
if(style == 'a') { //升序
Bubble_ascending(a,n);
printf("The result of ascending by bubbling is:\n");
show(fun1, a, n);
Select_ascending(a, n);
printf("The result of ascending by selecting is:\n");
show(fun1, a, n);
} else if(style =='d') { //降序
Bubble_descending(a,n);
printf("The result of descending by bubbling is:\n");
show(fun1, a, n);
Select_descending(a, n);
printf("The result of descending by selecting is:\n");
show(fun1, a, n);
} else
printf("Your style is wrong!\n");
}
int main() {
int a[N];
int n, i;
char style;
printf("Input the number of series:");
scanf("%d", &n);
printf("Input the series:\n");
for(i = 0; i < n; i++)
scanf("%d", &a[i]);
printf("Enter the style what you want(a means ascend,d means descend):");
scanf(" %c", &style);
SORT(a, n, style);
return 0;
}
(三)链表的操作(链表的建立,访问,删除链表指定结点,增加结点)
建立一个动态链表,将学生数据(学号,成绩)存入链表结构中,实现链表的访问(求学生成绩的平均分,找到最高分,最低分,将其数据输出);删除指定学号的学生数据,对学生数据进行排序,分别在链表头部,中间,末尾插入学生数据。
- 代码一
#include <stdio.h>
#include <malloc.h>
#define LEN sizeof(struct student)
struct student {
long num;
float score;
struct student *next;
};
int n;
struct student *creat(void) { /*这是建立链表函数*/
struct student *head;
struct student *p1, *p2;
n = 0;
p1 = p2 = (struct student *)malloc(LEN);
scanf("%ld,%f", &p1->num, &p1->score);
head = NULL;
while(p1->num != 0) {
n = n + 1;
if(n == 1)
head = p1;
else
p2->next = p1;
p2 = p1;
p1 = (struct student *)malloc(LEN);
scanf("%ld,%f", &p1->num, &p1->score);
}
p2->next = NULL;
return(head);
}
void print(struct student *head) { /*这是输出链表函数*/
struct student *p;
printf("\n这%d个学生的成绩记录为:\n", n);
p = head;
if(head != NULL)
do {
printf("%ld %5.1f\n", p->num, p->score);
p = p->next;
}while(p != NULL);
}
void numbermax(struct student *head) { /*这是找出学生最高分的函数*/
struct student *p1, *p2;
p1 = head;
if(head == NULL) {
printf("列表为空\n");
} else if (p1->next == NULL) {
printf("现在,这些学生最高分的是:\n");
printf("%5.1f\n", p1->score);
} else {
printf("现在,这些学生最高分的是:\n");
p2 = p1->next;
do {
if(p2->score > p1->score)
p1 = p2;
p2 = p2->next;
} while(p2 != NULL);
printf("%5.1f\n", p1->score);
}
}
void numbermin(struct student *head) { /*这是找出学生最低分的函数*/
struct student *p1, *p2;
p1 = head;
if(head == NULL) {
printf("列表为空\n");
} else if(p1->next == NULL) {
printf("现在,这些学生最低分的是:\n");
printf("%5.1f\n", p1->score);
} else {
printf("现在,这些学生最低分的是:\n");
p2 = p1->next;
do {
if(p2->score < p1->score)
p1 = p2;
p2 = p2->next;
} while(p2 != NULL);
printf("%5.1f\n", p1->score);
}
}
void numberavr(struct student *head) { /*这是找出学平均分的函数*/
struct student *p1;
float sum = 0, avr = 0, n = 0;
p1 = head;
if(head == NULL) {
printf("列表为空\n");
} else if(p1->next == NULL) {
printf("现在,这些学生的平均分是:\n");
printf("%5.1f\n", p1->score);
} else {
printf("现在,这些学生的平均分是:\n");
while(p1 != NULL) {
sum = sum + p1->score;
p1 = p1->next;
n = n + 1;
}
avr = sum / n;
printf("%5.1f\n", avr);
}
}
void scores(struct student *head) { /*这是学生分数的排序函数*/
struct student *p1, *p2;
float i;
long t;
printf("这是学生分数从低到高的排序\n");
p1 = head;
if(head == NULL) {
printf("该列表为空表\n");
} else {
while(p1 != NULL) {
p2 = p1->next;
while(p2 != NULL) {
if(p1->score > p2->score) {
i = p2->score;
p2->score = p1->score;
p1->score = i;
t = p2->num;
p2->num = p1->num;
p1->num = t;
}
p2 = p2->next;
}
p1 = p1->next;
}
}
while(head != 0) {
printf("%ld %5.1f\n", head->num, head->score);
head = head->next;
}
}
struct student *del(struct student *head, long num) { /*这是删除结点的函数*/
struct student *p1, *p2;
if(head == NULL) {
printf("\n列表为空!\n");
goto end;
}
p1 = head;
while(num != p1->num && p1->next != NULL) {
p2 = p1;
p1 = p1->next;
} if(num == p1->num) {
if(p1 == head)
head = p1->next;
else
p2->next = p1->next;
printf("delete:%ld\n", num);
n = n - 1;
}
else printf("%ld 找不到这个学号!\n",num);
end:
return(head);
}
struct student *insert(struct student *head, struct student *stud) { /*这是插入结点的函数*/
struct student *p0, *p1, *p2;
p1 = head;
p0 = stud;
if(head == NULL) {
head = p0;
p0->next = NULL;
} else {
while((p0->num > p1->num) && (p1->next != NULL)) {
p2 = p1;
p1 = p1->next;
}
if(p0->num <= p1->num) {
if(head == p1)
head = p0;
else
p2->next = p0;
p0->next = p1;
} else {
p1->next = p0;
p0->next = NULL;
}
}
n = n + 1;
return(head);
}
void main() { /*这是主函数*/
struct student *head, *stu;
long del_num;
printf("请输入学生的成绩记录:\n");
head = creat();
print(head);
numbermax(head);
numbermin(head);
numberavr(head);
scores(head);
printf("\n请输入要删除的学生数据的学号:");
scanf("%ld", &del_num);
while(del_num != 0) {
head = del(head, del_num);
print(head);
numbermax(head);
numbermin(head);
numberavr(head);
scores(head);
printf("请输入要删除的学生数据的学号:");
scanf("%ld", &del_num);
}
printf("\n请输入要插入的学生数据:");
stu = (struct student *)malloc(LEN);
scanf("%ld,%f", &stu->num, &stu->score);
while(stu->num != 0) {
head = insert(head,stu);
print(head);
numbermax(head);
numbermin(head);
numberavr(head);
scores(head);
printf("请输入要插入的学生数据:");
stu = (struct student *)malloc(LEN);
scanf("%ld,%f", &stu->num, &stu->score);
}
}
- 代码二
#include <stdio.h>
#include <stdlib.h>
typedef struct LNode{
int number; //学生学号
float score; //成绩
struct LNode *next;
}LNode, *LinkList;
LinkList p;
LinkList CreateList(LinkList La, int n) { //建立并储存动态链表的信息
int i;
LinkList r;
La = (LinkList)malloc(sizeof(LNode));
La->next = NULL;
r = La;
for(i = 0; i < n; i++) {
p = (LinkList)malloc(sizeof(LNode));
printf("请输入学生学号:");
scanf("%d", &p->number);
printf(" 成绩:");
scanf("%f", &p->score);
printf("\n");
p->next = NULL;
r->next = p;
r = p;
}
return La;
}
void DisplayList(LinkList La) { //输出学生的学号和成绩
p = La->next;
while(p != NULL)
{
printf("学生学号:%d 成绩:%.3f", p->number, p->score);
p = p->next;
printf("\n");
}
}
void Average(LinkList La, int n) { //求平均分
float sum, ave;
p = La->next;
sum = 0;
while(p != NULL) {
sum = sum + p->score;
p = p->next;
}
ave = sum / n;
printf("他们的平均分是: %.3f\n",ave);
}
void High_score(LinkList La) { //求最高分
LinkList p1;
p = La->next;
p1 = p->next;
do {
if( p->score < p1->score )
p = p1;
p1 = p1->next;
} while(p1 != NULL);
printf("他们的最高分是: %.3f\n", p->score);
}
void Low_score(LinkList La) { //求最低分
LinkList p1;
p = La->next;
p1 = p->next;
do {
if(p->score > p1->score)
p = p1;
p1 = p1->next;
} while(p1 != NULL);
printf("他们的最低分是: %.3f\n", p->score);
}
void DeleteList(LinkList La, int dele) { //删除指定学号的学生数据
LinkList p1, p2;
p1 = La;
p2 = La->next;
while(p2){
if(p2->number == dele)
p1->next = p2->next;
p1 = p2;
p2 = p2->next;
}
printf("现在的学生信息为:\n");
DisplayList(La);
}
void SortList(LinkList La) { //对学生数据进行排序
LinkList p1, p2;
int num_temp;
float score_temp;
p1 = La->next;
while(p1 != NULL) {
p2 = p1->next;
while(p2 != NULL) {
if(p1->score > p2->score) {
num_temp = p2->number;
p2->number = p1->number;
p1->number = num_temp; //交换学生学号
score_temp = p2->score;
p2->score = p1->score;
p1->score = score_temp; //交换成绩
}
p2 = p2->next;
}
p1 = p1->next;
}
printf("从低到高的成绩排序是: \n");
DisplayList(La);
}
//插入学生数据
void InsertList(LinkList La, int locate, int insert_num, float insert_score) {
LinkList p, N;
int i = 0;
p = La;
while(p && i < locate - 1) {
p = p->next;
++i;
}
if(!p || i > locate - 1)
printf("The given position is invalid!\n");
else {
N = (LinkList)malloc(sizeof(LNode));
N->number = insert_num;
N->score = insert_score;
N->next = p->next;
p->next = N;
DisplayList(La);
}
}
int main() {
int n, dele, locate, insert_num;
float insert_score;
LNode L;
LinkList L1;
printf("请输入学生个数:");
scanf("%d", &n);
printf("\n");
L1 = CreateList(&L, n);
DisplayList(L1);
Average(L1, n);
High_score(L1);
Low_score(L1);
printf("\n请输入要删除的学生数据的学号:");
scanf("%d", &dele);
DeleteList(L1, dele);
printf("\n");
SortList(L1);
printf("请输入要插入的学生数据的位置:");
scanf("%d", &locate);
printf("请输入学生学号:");
scanf("%d", &insert_num);
printf(" 成绩:");
scanf("%f", &insert_score);
printf("\n");
InsertList(L1, locate, insert_num, insert_score);
return 0;
}
(四) 学生成绩文件管理
定义一个结构体数组,存放10个学生的学号,姓名,三门课的成绩,输出单门课成绩最高的学生的学号、姓名、以及该门课程的成绩,输出三门课程的平均分数最高的学生的学号、姓名及其平均分,将10个学生的相关数据,存入文件中,再从文件中读出,按照平均分数从高到低进行排序,分别将结果输出到屏幕上和另一文件中,再从文件中读取第 1 ,3 , 5 ,7, 9个学生的数据。
1. 定义一个结构体数组,存放10个学生的学号,姓名,三门课的成绩
2. 从键盘输入10个学生的以上内容
3. 输出单门课成绩最高的学生的学号、姓名、以及该门课程的成绩
4. 输出三门课程的平均分数最高的学生的学号、姓名及其平均分
5. 从键盘输入10个学生的以上内容,存入文件stud.dat,关闭文件
6. 打开stud.dat文件,将数据读出,查看是否正确写入,关闭文件。
7. 打开文件stud.dat文件,读出数据,将10个学生按照平均分数从高到低进行排序,
分别将结果输出到屏幕上和另一文件studsort.dat中。
8. 从studsort.dat 文件中读取第1,3,5,7,9个学生的数据。
#include <stdio.h>
#define N 10
struct student
{
char num[6];
char name[20];
float score[3];
float avr;
}stu[N], temp;
void save() { //存入文件stud.dat,关闭文件
FILE *fp;
int i;
if((fp = fopen("stud.dat", "wb")) == NULL) {
printf("不能打开文件\n");
return;
}
for(i = 0; i < N; i++)
if(fwrite(&stu[i], sizeof(struct student), 1, fp) != 1)
printf("文件输出有误\n");
fclose(fp);
}
void sort() {
FILE *fp1, *fp2;
int i, j;
if((fp1 = fopen("stud.dat", "rb")) == NULL ) {
printf("不能打开文件\n\n");
return;
}
if((fp2 = fopen("studsort.dat", "wb")) == NULL ) {
printf("文件输出有误\n");
return;
}
for(i = 0; i < N; i++) {
if(fread(&stu[i], sizeof(struct student), 1, fp1) != 1) {
printf("文件读入有误\n");
return;
}
}
for(i = 0; i < N; i++) {
for(j = i + 1; j < N; j++)
if(stu[i].avr < stu[j].avr) {
temp = stu[i];
stu[i] = stu[j];
stu[j] = temp;
}
fwrite(&stu[i], sizeof(struct student), 1, fp2);
}
fclose(fp1);
fclose(fp2);
}
int main() {
int i, j, maxi;
float sum, max;
FILE *fp1, *fp2;
for(i = 0; i < N; i++) { //输入学生的数据
printf("请输入学生的学号姓名和3个成绩 %d:\n", i + 1);
printf("学号:");
scanf("%s", stu[i].num);
printf("姓名:");
scanf("%s", stu[i].name);
for(j = 0; j < 3; j++) {
printf("成绩%d:", j + 1);
scanf("%f", &stu[i].score[j]);
}
printf("\n");
}
//输出单门成绩最高的学生
max = 0;
maxi = 0;
for(j = 0; j < 3; j++) {
max = 0;
for(i = 0; i < N; i++)
if(stu[i].score[j] > max) {
max = stu[i].score[j];
maxi = i;
}
printf("score %d 最高分的学生是: %s,%s.\n", j+1, stu[maxi].num, stu[maxi].name);
printf("score %d 的分数为 %6.2f\n", j+1, stu[maxi].score[j]);
}
//输入三门课程的平均分最高的学生
for(i = 0; i < N; i++) {
sum = 0;
for(j = 0; j < 3; j++)
sum += stu[i].score[j];
stu[i].avr = sum / 3;
if(sum > max) {
max = sum;
maxi = i;
}
}
printf("三门课程的平均分最高的学生: student %s,%s.\n", stu[maxi].num, stu[maxi].name);
printf("该平均分是: %6.2f\n", stu[maxi].avr);
save();
fp1 = fopen("stud.dat", "rb");
printf("%d个学生成绩:\n", N);
printf("\n 学号 姓名 成绩1 成绩2 成绩3\n");
for(i = 0; i < N; i++) {
fread(&stu[i], sizeof(struct student), 1, fp1);
printf("\n%-7s,%-3s,%6.2f,%6.2f,%6.2f\n",
stu[i].num, stu[i].name, stu[i].score[0], stu[i].score[1], stu[i].score[2]);
}
fclose(fp1);
//学生按平均分数从高到低进行排序
sort();
fp2 = fopen("studsort.dat", "rb");
printf("学生按平均分数从高到低排序: \n");
printf("\n 学号 姓名 成绩1 成绩2 成绩3\n");
for(i = 0; i < N; i++) {
fread(&stu[i], sizeof(struct student), 1, fp2);
printf("\n%-7s,%-3s,%6.2f,%6.2f,%6.2f\n",
stu[i].num, stu[i].name, stu[i].score[0], stu[i].score[1], stu[i].score[2]);
}
fclose(fp2);
//奇数学生的各个值
fp2 = fopen("studsort.dat", "rb");
printf("奇数学生的成绩: \n");
printf("\n 学号 姓名 成绩1 成绩2 成绩3\n");
for(i = 0; i < N; i = i + 2){
fread(&stu[i], sizeof(struct student), 1, fp2);
printf("\n%-7s,%-3s,%6.2f,%6.2f,%6.2f\n",
stu[i].num, stu[i].name, stu[i].score[0], stu[i].score[1], stu[i].score[2]);
}
fclose(fp2);
return 0;
}