数据结构课程设计(含5个课程设计题目)

                                          课程设计报告

  • 课程设计概述

本次数据结构课程设计共完成5个题目:成绩分析问题,哈夫曼编码器,迷宫问题,八皇后问题,农夫过河问题的求解。

使用环境:C语言。

编译环境:Visual Studio 2022。

  • 课程设计题目

                                          1.《成绩分析问题》

(1)实验内容:

成绩分析问题。

(2)问题描述:

设计并实现一个成绩分析系统,能够实现录入,保存一个班级学生多门课程的成绩,并对成绩进行分析等功能。

(3)需求分析:

经过分析,本系统需完成的主要功能如下:

  1. 通过键盘输入各学生的多门课程的成绩,建立相应的文件input.dat。
  2. 对文件input.dat中的数据进行处理,要求具有如下功能:
  1. 按各门课程成绩排序,并生成相应的文件输出。
  2. 计算每个人的平均成绩,按平均成绩排序,并生成文件。
  3. 求出各门课程的平均成绩,最高分,最低分,不及格人数,60~69分人数,70~79分人数,80~89分人数,90分以上人数。
  4. 根据姓名或学号查询某人的各门课程成绩,重名也要能处理。

(4)概要设计:

--=ADT=--

{

Student * SearchByName(Student *head, char *name)// 根据姓名查询学生信息

Student * SearchById(Student *head, char *id)// 根据学号查询学生信息

void Add(Student **head)// 添加一个学生

void Read(Student **head)// 读取文件中的学生信息

void Save(Student * head)// 保存学生信息到文件

void SortAndOutput(Student * head)// 按三门课程成绩排序并输出

void CalculateAverage(Student * head)// 计算每人三门课程的平均成绩并输出

void SortByAverageScoreAndOutput(Student * head)// 按三门课程平均成绩排序并输出

void Statistics(Student * head)// 统计三门课程各自的平均成绩,最高分,最低分,不及格人数,60~69分人数,70~79分人数,80~89分人数,90分以上人数

void ShowMenu() // 显示菜单 

}

(5)存储结构:

typedef struct student {

    char id[20]; // 学号

    char name[20]; // 姓名

    float math_score; // 数学成绩

    float english_score; // 英语成绩

    float computer_score; // 计算机成绩

    float average; // 平均成绩

    struct student * next; // 指向下一个学生的指针

} Student;

(6)设计思路:

 链表数据结构:使用链表来存储学生信息,每个节点表示一个学生。链表的好处是可以动态地添加和删除节点,灵活处理不同数量的学生信息。

   - 学生结构体:定义一个学生结构体,包含以下字段:学号、姓名、数学成绩、英语成绩、计算机成绩、平均成绩和指向下一个学生节点的指针。这样可以方便地存储和访问每个学生的相关信息。

   - 功能函数:实现各种功能函数,如添加学生、读取文件、保存文件、排序等。这些函数通过操作链表来完成相关操作。

(7)关键算法:

  - 冒泡排序算法:用于将学生根据指定的排序规则(如成绩)进行排序。冒泡排序算法的基本思想是比较相邻的两个元素,如果它们的顺序错误就交换位置,继续比较直到完成排序。在学生信息管理系统中,可以根据数学成绩、英语成绩或计算机成绩来排序学生信息。

   - 遍历链表:通过使用循环遍历链表的每个节点,可以实现对链表中的数据进行访问、处理和输出等操作。遍历链表是获取每个学生信息、计算平均成绩以及输出结果的关键步骤。

   - 文件读写:通过使用二进制文件读写方式,可以将学生信息保存到文件中,或从文件中读取学生信息。在学生信息管理系统中,可以将学生信息以二进制形式写入文件,并在需要时从文件中读取,并重新构建链表。

使用链表作为数据结构,结合冒泡排序算法、链表遍历和文件读写等算法,可以实现学生信息的管理、排序和存储等功能

(8)详细设计:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

// 定义学生结构体

typedef struct student {

    char id[20]; // 学号

    char name[20]; // 姓名

    float math_score; // 数学成绩

    float english_score; // 英语成绩

    float computer_score; // 计算机成绩

    float average; // 平均成绩

    struct student * next; // 指向下一个学生的指针

} Student;

// 根据姓名查询学生信息

Student * SearchByName(Student *head, char *name) {

    Student *p = head;

    while (p != NULL) {

        if (strcmp(p->name, name) == 0) { // 找到该学生

            return p;

        }

        p = p->next;

    }

    return NULL; // 没有找到该学生

}

// 根据学号查询学生信息

Student * SearchById(Student *head, char *id) {

    Student *p = head;

    while (p != NULL) {

        if (strcmp(p->id, id) == 0) { // 找到该学生

            return p;

        }

        p = p->next;

    }

    return NULL; // 没有找到该学生

}

// 添加一个学生

void Add(Student **head) {

    Student * p = (Student *)malloc(sizeof(Student));

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

    scanf("%s", p->id);

    printf("请输入学生的姓名:");

    scanf("%s", p->name);

    printf("请输入学生的数学成绩:");

    scanf("%f", &p->math_score);

    printf("请输入学生的英语成绩:");

    scanf("%f", &p->english_score);

    printf("请输入学生的计算机成绩:");

    scanf("%f", &p->computer_score);

    p->average = (p->math_score + p->english_score + p->computer_score) / 3; // 计算平均成绩

    // 插入到链表中

    Student * temp = NULL;

    Student * cur = *head;

    while(cur && p->average < cur->average) { // 按平均成绩排序插入

        temp = cur;

        cur = cur->next;

    }

    if(temp == NULL) {

        p->next = *head;

        *head = p;        

    } else {

        temp->next = p;

        p->next = cur;

    }

    printf("添加成功\n");

}

// 读取文件中的学生信息

void Read(Student **head) {

    FILE * fp = fopen("input.dat", "rb");

    if (fp == NULL) {

        printf("文件打开失败\n");

        return;

    }

    Student * p = (Student *)malloc(sizeof(Student));

    fread(p, sizeof(Student), 1, fp);

    while (!feof(fp)) {

        // 插入到链表后面

        p->next = *head;

        *head = p;

        p = (Student *)malloc(sizeof(Student));

        fread(p, sizeof(Student), 1, fp);

    }

    printf("读取成功\n");

    fclose(fp);

}

// 保存学生信息到文件

void Save(Student * head) {

    FILE * fp = fopen("input.dat", "wb");

    if (fp == NULL) {

        printf("文件打开失败\n");

        return;

    }

    Student * p = head;

    while (p != NULL) {

        fwrite(p, sizeof(Student), 1, fp);

        p = p->next;

    }

    printf("保存成功\n");

    fclose(fp);

}

// 按三门课程成绩排序并输出

void SortAndOutput(Student * head) {

    Student * p = head;

    int count = 0;

    while (p != NULL) {

        count++;

        p = p->next;

    }

    Student ** array = (Student **)malloc(sizeof(Student *) * count); // 存储指针的数组

    p = head;

    for (int i = 0; i < count; i++) {

        array[i] = p;

        p = p->next;

    }

    for (int i = 0; i < count - 1; i++) { // 冒泡排序

        for (int j = 0; j < count - 1 - i; j++) {

            if (array[j]->math_score + array[j]->english_score + array[j]->computer_score < array[j + 1]->math_score + array[j + 1]->english_score + array[j + 1]->computer_score) {

                Student * temp = array[j];

                array[j] = array[j + 1];

                array[j + 1] = temp;

            }

        }

    }

    FILE * fp = fopen("sorted_by_score.dat", "w");

    fprintf(fp, "%-20s%-20s%-20s%-20s%-20s%-20s\n", "学号", "姓名", "数学成绩", "英语成绩", "计算机成绩", "平均成绩");

    for (int i = 0; i < count; i++) {

        fprintf(fp, "%-20s%-20s%-20.1f%-20.1f%-20.1f%-20.1f\n", array[i]->id, array[i]->name, array[i]->math_score, array[i]->english_score, array[i]->computer_score, array[i]->average);

    }

    printf("排序成功并已保存到sorted_by_score.dat文件中\n");

    fclose(fp);

}

// 计算每人三门课程的平均成绩并输出

void CalculateAverage(Student * head) {

    FILE * fp = fopen("average_score.dat", "w");

    fprintf(fp, "%-20s%-20s%-20s%-20s%-20s%-20s\n", "学号", "姓名", "数学成绩", "英语成绩", "计算机成绩", "平均成绩");

    Student * p = head;

    while (p != NULL) {

        fprintf(fp, "%-20s%-20s%-20.1f%-20.1f%-20.1f%-20.1f\n", p->id, p->name, p->math_score, p->english_score, p->computer_score, p->average);

        p = p->next;

    }

    printf("每人三门课程的平均成绩已计算并保存到average_score.dat文件中\n");

    fclose(fp);

}

// 按三门课程平均成绩排序并输出

void SortByAverageScoreAndOutput(Student * head) {

    Student * p = head;

    int count = 0;

    while (p != NULL) {

        count++;

        p = p->next;

    }

    Student ** array = (Student **)malloc(sizeof(Student *) * count); // 存储指针的数组

    p = head;

    for (int i = 0; i < count; i++) {

        array[i] = p;

        p = p->next;

    }

    for (int i = 0; i < count - 1; i++) { // 冒泡排序

        for (int j = 0; j < count - 1 - i; j++) {

            if (array[j]->average < array[j + 1]->average) {

                Student * temp = array[j];

                array[j] = array[j + 1];

                array[j + 1] = temp;

            }

        }

    }

    FILE * fp = fopen("sorted_by_average_score.dat", "w");

    fprintf(fp, "%-20s%-20s%-20s%-20s%-20s%-20s\n", "学号", "姓名&#

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
采用C++编写,完成了题目的所有要求,并附有说明文档。 大学的每个专业都要制定教学计划。假设任何专业都有固定的学习年限,每学年两学 期,每学期的时间长度和学分上限值均相等,每个专业开设的课程都是确定的,而且课程在 开设时间的安排必须满足先修关系。每门课程有哪些先修课程是确定的,可以有任意多门, 也可以没有。每门课恰好占一个学期。试在这样的前提下设计一个教学计划编制程序。 [基本要求] (1)输入参数包括:学期总数,一学期的学分上限,每门课的课程号(固定占3位的字母数字串)、学分和直接先修课的课程号。 (2)允许用户指定下列两种编排策略之一:一是使学生在各学期中的学习负担尽量均匀;二是使课程尽可能地集中在前几个学期中。 (3)若根据给定的条件问题无解,则报告适当的信息;否则将教学计划输出到用户指定的文件中。计划的表格格式自行设计。 [测试数据] 学期总数:6;学分上限:10;该专业共开设12门课,课程号从C01到C12,学分顺序为2,3,4,3,2,3,4,4,7,5,2,3。先修关系如下: 课程编号 课程名称 先决条件 C1 程序设计基础 无 C2 离散数学 C1 C3 数据结构 C1,C2 C4 汇编语言 C1 C5 语言的设计和分析 C3,C4 C6 计算机原理 C11 C7 编译原理 C5,C3 C8 操作系统 C3,C6 C9 高等数学 无 C10 线性代数 C9 C11 普通物理 C9 C12 数值分析 C9,C10,C1 [实现提示] 可设学期总数不超过12,课程总数不超过100。如果输入的先修课程号不在该专业开设的课程序列中,则作为错误处理。应建立内部课程序号与课程号之间的对应关系。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

buyehou_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值