利用堆排序实现学生成绩管理

问题遇到的现象和发生背景

用vs2019写利用堆排序实现学生成绩管理

代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int n;
typedef struct student {
char num[20];
char name[25];
int score;
}*Stu, StuNode;

void Build(Stu stu)
{
FILE* fp;
char name[20];
int score, i;
char num[20];
fp = fopen("E:\Student.txt", "w");
printf("请输入学生人数:");
scanf("%d", &n);

printf("请输入学生信息(学号,姓名,成绩):\n");
for (i = 1; i <= n; i++)
{
    scanf("%s %s %d", num, name, &score);
    fprintf(fp, "%s %s %d\n", num, name, score);
}
printf("登录成功.\n");
fclose(fp);

}
void ReadFile(Stu& stu)
{//读文件,存到Stu结构体中
FILE* fp;
int i;
stu = (Stu)malloc(sizeof(StuNode) * (n + 1));
fp = fopen("E:\Student.txt", "r");
for (i = 1; i <= n; i++)
fscanf(fp, "%s %s %d", stu[i].num, stu[i].name, &stu[i].score);

fclose(fp);

}

void Display(Stu stu)
{//显示数据
int i;
int temp = 1, index = 0;
for (i = 1; i <= n; i++)
{
printf("%2d %15s %15s %5d\n", temp, stu[i].num, stu[i].name, stu[i].score);
if (i < n && stu[i].score == stu[i + 1].score)
index++;
else
{
temp += index + 1;
index = 0;
}
}

free(stu);

}

void Swap(StuNode& a, StuNode& b)
{
StuNode temp;
temp = a;
a = b;
b = temp;
}

void HeapAdjust(Stu stu, int s, int m)
{//调整堆
int j;
StuNode rc;
rc = stu[s];

for (j = 2 * s; j <= m; j *= 2)
{
    if (j<m && stu[j].score>stu[j + 1].score)
        j++;
    if (!(rc.score > stu[j].score))
        break;
    stu[s] = stu[j];
    s = j;
}
stu[s] = rc;

}
void HeapSort(Stu stu)
{//堆排序
int i;
ReadFile(stu);
for (i = n / 2; i > 0; i--)
HeapAdjust(stu, i, n);
for (i = n; i > 1; i--)
{
Swap(stu[1], stu[i]);
HeapAdjust(stu, 1, i - 1);
}
Display(stu);
}

int main()
{
Stu stu;
int key;
while (1)
{
printf(" ----------------------\n");
printf(" 1.录入学生基本信息。\n");
printf(" 2.堆排序。\n");
printf(" 3.输出学生信息。\n");
printf(" 4.退出。\n");
printf(" ----------------------\n");
scanf("%d", &key);
stu = NULL;
switch (key)
{
case 1:
Build(stu);
break;
case 2:
HeapSort(stu);
break;
case 3:
ReadFile(stu);
Display(stu);
break;
default:
return 0;
}
}
}

运行结果及报错内容

img

我想要达到的结果

正常运行


//排序:
/*  
    1、录入学生基本信息
    2、直接插入排序
    3、冒泡排序
    4、快速排序
    5、简单选择排序
    6、堆排序
    7、2-路归并排序
    8、输出学生信息
*/
#include<stdio.h>
#include<stdlib.h>
typedef struct{
    char name[20];
    int num;
    int score;
    int degree;
}Student,*student;
int save(student w,int n)
{
    FILE *fp;
    if((fp=fopen("stu.txt","wb"))==NULL)
    {
        printf("cannot creat the file!\n");
        return 1;
    }
    for(int i=1;i<=n;i++)
    {
        fwrite(w+1,sizeof(Student),1,fp);
        w++; 
    }
    fclose(fp);
    return 0;
}
void Studentinfo(student stu,int n)
{
    int i;    
    printf("录入学生的信息:\n");
    printf("姓名   学号   分数:\n");
    for(i=1;i<=n;i++)
    {
        scanf("%s",stu[i].name);
        scanf("%d",&stu[i].num);
        scanf("%d",&stu[i].score);    
        getchar();
    }
    save(stu,n);
}
 
int openfile(student p,int n)
{
    FILE *fp;
    if((fp=fopen("stu.txt","rb"))==NULL)
    {
        printf("cannot open the file!\n");
        return 1;
    }
    for(int i=1;i<=n;i++)
    {
        fread(p+1,sizeof(Student),1,fp);
        p++;
    }
    fclose(fp);    
    return 0;
}
void showinfo(student stu,int n)
{
    int i;
    printf("进行排序后学生的信息:\n");
    printf("姓名   学号   分数   名次:\n");
    for(i=1;i<=n;i++)
    {
        stu[i].degree=n-i+1;
        printf("%s ",stu[i].name);
        printf("%5d%5d%5d\n",stu[i].num,stu[i].score,stu[i].degree);
    }
}
void InsertSort(student stu,int n)
{
    int i,j;
    for(i=2;i<=n;i++)
    {
        if(stu[i].score<stu[i-1].score)
        {
            stu[0]=stu[i];
            stu[i]=stu[i-1];
            for(j=i-2;stu[0].score<stu[j].score;j--)
                stu[j]=stu[j-1];
            stu[j+1]=stu[0];
        }
    }
    showinfo(stu,n);        
}
void BubbleSort(student stu,int n)
{
    int i,j;
    int flag=1;
    Student t;
    for(i=1;i<=n&&flag;i++)
    {
        flag=0;
        for(j=1;j<=n-i;j++)
        {
            if(stu[j].score>stu[j+1].score)
            {
                flag=1;
                t=stu[j];
                stu[j]=stu[j+1];
                stu[j+1]=t;
            }
        }
    }
    showinfo(stu,n);
}
int Partition(student &stu,int low,int high)
{
    stu[0]=stu[low];
    int   keyword=stu[low].score;
    while(low<high){
 
        while(low<high&&stu[high].score>=keyword)
            high--;
        stu[low]=stu[high];
        while(low<high&&stu[low].score<=keyword)
            low++;
        stu[high]=stu[low];
    }
    stu[low]=stu[0];
    return low;
}
void QSort(student &stu,int low,int high)
{
    int temp;
    if(low<high)
    {
        temp=Partition(stu,low,high);
        QSort(stu,low,temp-1);
        QSort(stu,temp+1,high);
    }
}
void SlectsSort(student stu,int n)
{
    int i,j,k;
    Student temp;
    for(i=1;i<n;i++)
    {
        k=i;
        for(j=i+1;j<=n;j++)
            if(stu[k].score>stu[j].score)
                k=j;
        if(k!=i)
        {
            temp=stu[i];
            stu[i]=stu[k];
            stu[k]=temp;
        }
    }
    showinfo(stu,n);
}
void HeapAdjust(student stu,int s,int n)
{
    
    Student rc;
    rc=stu[s];
    for(int j=2*s;j<=n;j*=2)
    {
        if(j<n&&stu[j].score<stu[j+1].score)
            j++;
        if(rc.score>stu[j].score) break;
        stu[s]=rc;
    }
}
void HSort(student stu,int n)
{//堆排序
    int i;
    Student t;
    for(i=n/2;i>0;i--)
        HeapAdjust(stu,i,n);
    for(i=n;i>1;i--)
    {
        t=stu[1];
        stu[1]=stu[i];
        stu[i]=t;
        HeapAdjust(stu,1,i-1);
    }
        
}
student S;
void merge(Student stu[],int i,int m,int n)
{
    int j,k;
    j=m+1;
    k=i;
    while(j<=n&&i<=m)
    {
        if(stu[i].score<=stu[j].score)
            S[k++]=stu[i++];
        else 
            S[k++]=stu[j++];
    }
    while(j<=n)
        S[k++]=stu[j++];
    while(i<=m)
        S[k++]=stu[i++];
    for(int t=i;t<=n;t++)
        stu[t]=S[t];
}
void MergeSort(student stu,int low,int high)
{
    if(low==high)
        return;
    int m;
    m=(low+high)/2;
    MergeSort(stu,low,m);
    MergeSort(stu,m+1,high);
    merge(stu,low,m,high);
}
int main()
{
    student stu;
    int n,low,high;
    printf("请输入学生个数:\n");
    scanf("%d",&n);
    low=1;high=n;
    stu=(student)malloc((n+1)*sizeof(Student));
    Studentinfo(stu,n);
    openfile(stu,n);
    InsertSort(stu,n);
    openfile(stu,n);
    BubbleSort(stu,n);
    openfile(stu,n);
    QSort(stu,low,high);
    showinfo(stu,n);
    openfile(stu,n);
    SlectsSort(stu,n);
    HSort(stu,n);
    showinfo(stu,n);
    /*MergeSort(stu,low,high);
    showinfo(stu,n);*/
    return 0;    
}

我发个能正常运行的堆排序给你

/*④ 生成500个在[200, 10000]之间的整数保存数组A中,以此数组元素作为关键字,
采用堆排序算法按非递减方式进行排序,给出操作的结果及相应的操作次数;*/
#include <stdio.h>
#include<stdlib.h>
#define numOfd 5 
typedef int data;//类型改名
typedef struct DataType
{
  data key;
}DataType;

//堆排序算法
//(1)最大堆调整
void CreatHeap(DataType a[],int n,int h)
{
    //调整非叶节点a[h]使之满足最大堆,n为数组a的元素个数,h为:(n-2)/2
    int i,j,flag;
    DataType temp;
    i=h;                                 //i为要建堆的二叉树根结点下标
    j=2*i+1;                             //j为i的左孩子结点的下标
    temp=a[i];
    flag=0;

    //沿左右孩子中值较大者重复向下筛选
    while(j<n&&flag!=1){
        //寻找左右孩子结点中的较大者,j为其下标
        if(j<n-1&&a[j].key<a[j+1].key)j++;//这里完成了对于根左右孩子结点值的比较
        if(temp.key>a[j].key)
           flag=1;         //标记结束筛选条件
        else{              //否则把a[j]上移
            a[i]=a[j];
            i=j;
            j=2*i+1;
        }
    }
    a[i]=temp;            //把最初的a[i]赋值给最后的a[j]
}
//(2)创建最大堆
void InitCreatHeap(DataType a[],int n)
{
    //把a[0]~a[n-1]初始化创建为最大堆
    int i;
    for(i=(n-2)/2;i>=0;i--)
    {
        CreatHeap(a,n,i);
    }
}
//(3)堆排序
void HeapSort(DataType a[],int n)
{
   int i;
   DataType temp;
   InitCreatHeap(a,n);      //初始化创建最大堆
   for(i=n-1;i>0;i--)
   {
    temp=a[0];
    a[0]=a[i];
    a[i]=temp;
    CreatHeap(a,i,0);      //调整根结点满足最大堆,只需要对根结点进行最大堆化,其它的已满足最大堆
   }
}
//生成由随机数组成的数组
DataType *rand_array(int number,int min,int max)
{
    int i;
    DataType *a=NULL;
    a=(DataType *)malloc(number*sizeof(int));
    for(i=0;i<number;i++)
        {
            a[i].key=rand()%(max-min+1)+min;
        }
    return a;
}
//输出排序后的结果
void print(DataType a[],int numOfA)
{
    int i;
    for(i=0;i<numOfA;i++)
        {
            if(i%20==0){printf("\n");}
            printf("%d   ",a[i].key);
        }
}
int main(){
        DataType *c=rand_array(500,200,10000);
        printf("排序前:\n");
        print(c,500);
        HeapSort(c,500);
        printf("\n");
        printf("\n堆排序后:\n");
        print(c,500);
        return 0;
  
}

数据结构-学生成绩管理系统
如有帮助,望采纳
https://blog.csdn.net/m0_46633875/article/details/114187151

Expression: stream!= nullptr
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
表达式:stream!=空指针
有关程序如何导致断言的信息
失败,请参阅有关断言的Visual C++文档。
(按“重试”调试应用程序)
错误大概意思是
数据流为空,原因有文件不存在、流为空
主要检查下代码下文件名称、路径。传入参数