user-0 提问: 关于学生成绩管理系统排序问题

回复:
user: user-1
content: 楼主，这个链表是表头插入法，插入的最后一个节点就是表头，所以排序也是从最后一个开始的，而不是k=p->pNext 开始，修改如下见标注，供参考：#include<stdio.h> #include<conio.h> #include<stdlib.h> #include<string.h>  //定义一个学生的信息 typedef struct _Student {   int total;      //总成绩 }Student;  //定义一个节点 typedef struct _Node {    Student stu;//学生    struct _Node* pNext; }Node;  Node*g_pHead=NULL;             //头结点  void Menu();//菜单界面函数 void Input_m();//成绩录入函数 void Print();//成绩显示函数 void Save();//成绩保存函数 void Order();//成绩排序函数 void Modify();//成绩修改函数 void Sta();//声明成绩统计函数  int main() {     int a;     while(1){  //while循环使程序持续运行              Menu();              scanf("%d",&a);              switch(a)//**用户进行选择**//                    {                       case 1:                            Input_m(); //成绩录入                            break;                       case 2:                            Print();//成绩显示                            break;                       case 4:                            Order();//成绩排序                            break;                       case 7:                           printf("您已成功退出系统，欢迎下次使用！\n");                           return 0;                      default:                           printf("无效选择，请重新输入\n");                           system("pause");                           system("cls");                           break;              }     }     return 0; }  void Menu()//菜单界面函数  {         printf("\t\t\t欢迎使用学生班级成绩管理系统！\n");         printf("\t\t=============================================\n");         printf("\t\t==\t          主菜单                   ==\n");         printf("\t\t=============================================\n");         printf("\t\t==\t\t1.成绩录入                 ==\n");         printf("\t\t==\t\t2.成绩显示                 ==\n");         printf("\t\t==\t\t4.成绩排序                 ==\n");         printf("\t\t==\t\t7.系统退出                 ==\n");         printf("\t\t=============================================\n");         printf("\t\t===========请选择相应的功能列表==============\n");      } void Input_m()//成绩录入函数 {     Node* pNewNode =(Node*)malloc(sizeof(Node));//创建一个新节点     pNewNode->pNext=NULL;     if(g_pHead==NULL)       {         g_pHead=pNewNode;       }     else       {         pNewNode->pNext=g_pHead;         g_pHead=pNewNode;       }     printf("请输入学生的总成绩：\n");     scanf("%d",&pNewNode->stu.total);     printf("学生成绩录入成功！\n");     system("pause");      //暂停执行     system("cls");        //清屏 }  void Print()//成绩显示函数  {     system("cls");     printf("                     学生成绩表                         \n");     printf("========================================================\n");     printf("总成绩\n");      //遍历链表，一次打印出学生的成绩     Node* p=g_pHead;     while(p!=NULL)      {         printf("%d \n",p->stu.total);         p=p->pNext;//指向下一个，少了这个会无限循环      }     system("pause"); }  int trival(Node*g_pHead) {     Node* p=g_pHead;     int i=0;     Node* w;     w = p;             //w=p->pNext ;  //这句修改     while(w!=NULL)     {       w=w->pNext ;       i++;     }     return i; }  void Order()//总成绩排序函数 {     Node* p=g_pHead;     Node* k,*q;     int n,i,j;     Student temp;     n=trival(g_pHead);                    //这句修改     for(i=0,k=p ;i<n-1;i++,k=k->pNext )   //for(i=0,k=p->pNext ;i<n-1;i++,k=k->pNext )       {         for(j=i+1,q=k->pNext; j<n ; q=q->pNext ,j++)           {               if(k->stu.total> q->stu.total )                 {                    temp=k->stu ;                    k->stu =q->stu ;                    q->stu =temp;                 }           }       }     printf("总成绩由低到高依次排序为：\n");     while(p!=NULL){          printf("%d\n",p->stu.total);          p=p->pNext;     }     system("pause");     system("cls"); }

user: user-0
content: 引用 7 楼 user-1 的回复:我算知道毛病了，我改的是： 楼主改的：   我改的： 楼主改的：  两条语句，楼主一句未改？ 哦哦哦，对不起对不起，我看错了，能像你那样子运行了，问题已经解决了，谢谢你！

user: user-1
content: 第114行 ：w=p; 第 130行：for(i=0,k=p; i<n-1; i++,k=k->pNext)

user: user-1
content: 我算知道毛病了，我改的是： 楼主改的：   我改的： 楼主改的：  两条语句，楼主一句未改？

user: user-1
content: 这是按楼主的步骤，按改过的代码运行（ w =p->pNext; //w=p->pNext ;  //这句修改（已改）   for(i=0,k=p->pNext ;i<n-1;i++,k=k->pNext )   //for(i=0,k=p->pNext ;i<n-1;i++,k=k->pNext )（已改）），执行的结果，已经没有楼主讲的问题了：//按楼主讲的步骤： //录入第一个数：                          欢迎使用学生班级成绩管理系统！                 =============================================                 ==                主菜单                   ==                 =============================================                 ==              1.成绩录入                 ==                 ==              2.成绩显示                 ==                 ==              4.成绩排序                 ==                 ==              7.系统退出                 ==                 =============================================                 ===========请选择相应的功能列表============== 1 请输入学生的总成绩： 1 学生成绩录入成功！ 请按任意键继续. . .   //录入第二个数：                         欢迎使用学生班级成绩管理系统！                 =============================================                 ==                主菜单                   ==                 =============================================                 ==              1.成绩录入                 ==                 ==              2.成绩显示                 ==                 ==              4.成绩排序                 ==                 ==              7.系统退出                 ==                 =============================================                 ===========请选择相应的功能列表============== 1 请输入学生的总成绩： 2 学生成绩录入成功！ 请按任意键继续. . .   //录入第三个数：                          欢迎使用学生班级成绩管理系统！                 =============================================                 ==                主菜单                   ==                 =============================================                 ==              1.成绩录入                 ==                 ==              2.成绩显示                 ==                 ==              4.成绩排序                 ==                 ==              7.系统退出                 ==                 =============================================                 ===========请选择相应的功能列表============== 1 请输入学生的总成绩： 3 学生成绩录入成功！ 请按任意键继续. . .   //然后执行排序；                          欢迎使用学生班级成绩管理系统！                 =============================================                 ==                主菜单                   ==                 =============================================                 ==              1.成绩录入                 ==                 ==              2.成绩显示                 ==                 ==              4.成绩排序                 ==                 ==              7.系统退出                 ==                 =============================================                 ===========请选择相应的功能列表============== 4 总成绩由低到高依次排序为：  //这里也正常 1 2 3 请按任意键继续. . .  //选择 2.成绩显示  看看排序     这里没有乱序                       学生成绩表 ======================================================== 总成绩 1 2 3 请按任意键继续. . .    //继续再输入一个新的成绩                       学生成绩表 ======================================================== 总成绩 1 2 3 请按任意键继续. . .                         欢迎使用学生班级成绩管理系统！                 =============================================                 ==                主菜单                   ==                 =============================================                 ==              1.成绩录入                 ==                 ==              2.成绩显示                 ==                 ==              4.成绩排序                 ==                 ==              7.系统退出                 ==                 =============================================                 ===========请选择相应的功能列表============== 1 请输入学生的总成绩： 10 学生成绩录入成功！ 请按任意键继续. . .    //再执行排序 //【前面三个成绩就可以正常排序了，但是第四个录进来的成绩就没有 】？？？？？？？？ //【也就是说每次排序最后一个录入的成绩总是不能参与到排序过程中。】？？？？？？？                          欢迎使用学生班级成绩管理系统！                 =============================================                 ==                主菜单                   ==                 =============================================                 ==              1.成绩录入                 ==                 ==              2.成绩显示                 ==                 ==              4.成绩排序                 ==                 ==              7.系统退出                 ==                 =============================================                 ===========请选择相应的功能列表============== 4 总成绩由低到高依次排序为：//这里四个数 1 2 3 10 请按任意键继续. . .    //到这里再多加一步，选择 2.成绩显示 ，第四个也在                     学生成绩表 ======================================================== 总成绩 1 2 3 10 请按任意键继续. . .

user: user-0
content: 引用 3 楼 user-1 的回复:不存在了。表头插入法，就是每次输入一个数据时，在没有排序的情况下，最后这个输入的数据是排在第一位的，也就是倒序（这个倒序是指和输入的顺序相反，先入后出）的，最早输入的显示在最后一个。//这里随便输入三个数字，然后选择2 成绩显示：                       学生成绩表 ======================================================== 总成绩 6 0 3 请按任意键继续. . .  //这里是选择 4 成绩排序                         欢迎使用学生班级成绩管理系统！                 =============================================                 ==                主菜单                   ==                 =============================================                 ==              1.成绩录入                 ==                 ==              2.成绩显示                 ==                 ==              4.成绩排序                 ==                 ==              7.系统退出                 ==                 =============================================                 ===========请选择相应的功能列表============== 4 总成绩由低到高依次排序为： 0 3 6 请按任意键继续. . .  //这里是先选择 1.成绩录入 ，增加一个数10，然后选择2.成绩显示 ，10是最后加入的数字，在没有排序的时候 //它就是第一个，它就是表头。                       学生成绩表 ======================================================== 总成绩 10 0 3 6 请按任意键继续. . .   //这里是选择  4.成绩排序 。如果这时后接下去选择2.成绩显示，它就是显示已经排序好的排列了。                      学生成绩表 ======================================================== 总成绩 10 0 3 6 请按任意键继续. . .                         欢迎使用学生班级成绩管理系统！                 =============================================                 ==                主菜单                   ==                 =============================================                 ==              1.成绩录入                 ==                 ==              2.成绩显示                 ==                 ==              4.成绩排序                 ==                 ==              7.系统退出                 ==                 =============================================                 ===========请选择相应的功能列表============== 4 总成绩由低到高依次排序为： 0 3 6 10 请按任意键继续. . .  啊这。。。是修改了那两处对吧？我是按你标的来改的呀。 #include<stdio.h> #include<conio.h> #include<stdlib.h> #include<string.h>   //定义一个学生的信息 typedef struct _Student {   int total;      //总成绩 }Student;   //定义一个节点 typedef struct _Node {    Student stu;//学生    struct _Node* pNext; }Node;   Node*g_pHead=NULL;             //头结点   void Menu();//菜单界面函数 void Input_m();//成绩录入函数 void Print();//成绩显示函数 void Save();//成绩保存函数 void Order();//成绩排序函数 void Modify();//成绩修改函数 void Sta();//声明成绩统计函数   int main() {     int a;     while(1){  //while循环使程序持续运行              Menu();              scanf("%d",&a);              switch(a)//**用户进行选择**//                    {                       case 1:                            Input_m(); //成绩录入                            break;                       case 2:                            Print();//成绩显示                            break;                       case 4:                            Order();//成绩排序                            break;                       case 7:                           printf("您已成功退出系统，欢迎下次使用！\n");                           return 0;                      default:                           printf("无效选择，请重新输入\n");                           system("pause");                           system("cls");                           break;              }     }     return 0; }   void Menu()//菜单界面函数  {         printf("\t\t\t欢迎使用学生班级成绩管理系统！\n");         printf("\t\t=============================================\n");         printf("\t\t==\t          主菜单                   ==\n");         printf("\t\t=============================================\n");         printf("\t\t==\t\t1.成绩录入                 ==\n");         printf("\t\t==\t\t2.成绩显示                 ==\n");         printf("\t\t==\t\t4.成绩排序                 ==\n");         printf("\t\t==\t\t7.系统退出                 ==\n");         printf("\t\t=============================================\n");         printf("\t\t===========请选择相应的功能列表==============\n");       } void Input_m()//成绩录入函数 {     Node* pNewNode =(Node*)malloc(sizeof(Node));//创建一个新节点     pNewNode->pNext=NULL;     if(g_pHead==NULL)       {         g_pHead=pNewNode;       }     else       {         pNewNode->pNext=g_pHead;         g_pHead=pNewNode;       }     printf("请输入学生的总成绩：\n");     scanf("%d",&pNewNode->stu.total);     printf("学生成绩录入成功！\n");     system("pause");      //暂停执行     system("cls");        //清屏 }   void Print()//成绩显示函数  {     system("cls");     printf("                     学生成绩表                         \n");     printf("========================================================\n");     printf("总成绩\n");      //遍历链表，一次打印出学生的成绩     Node* p=g_pHead;     while(p!=NULL)      {         printf("%d \n",p->stu.total);         p=p->pNext;//指向下一个，少了这个会无限循环      }     system("pause"); }   int trival(Node*g_pHead) {     Node* p=g_pHead;     int i=0;     Node* w;     w =p->pNext;             //w=p->pNext ;  //这句修改（已改）     while(w!=NULL)     {       w=w->pNext ;       i++;     }     return i; }   void Order()//总成绩排序函数 {     Node* p=g_pHead;     Node* k,*q;     int n,i,j;     Student temp;     n=trival(g_pHead);                    //这句修改     for(i=0,k=p->pNext ;i<n-1;i++,k=k->pNext )   //for(i=0,k=p->pNext ;i<n-1;i++,k=k->pNext )（已改）       {         for(j=i+1,q=k->pNext; j<n ; j++,q=q->pNext ,j++)           {               if(k->stu.total> q->stu.total )                 {                    temp=k->stu ;                    k->stu =q->stu ;                    q->stu =temp;                 }           }       }     printf("总成绩由低到高依次排序为：\n");     while(p!=NULL){          printf("%d\n",p->stu.total);          p=p->pNext;     }     system("pause");     system("cls"); }

user: user-1
content: 上面的描述不规范，应该这么说，表头插入法，每次插入一个新节点时，都是把这个新节点作为头节点，所以头节点head始终指向最后录入的数据节点。你可以实验下，比如输入三个数，1 2 3 ，输入完后，选择2.成绩显示，它就是显示 3 2 1。你的代码里有没有文件保存和打开并读入文件的功能，如果有，你就会发现一个问题，当你这次保存时顺序是 1 2 3退出程序后，下次重新运行代码，文件载入时它显示的就是3 2 1.

user: user-1
content: 不存在了。表头插入法，就是每次输入一个数据时，在没有排序的情况下，最后这个输入的数据是排在第一位的，也就是倒序（这个倒序是指和输入的顺序相反，先入后出）的，最早输入的显示在最后一个。//这里随便输入三个数字，然后选择2 成绩显示：                       学生成绩表 ======================================================== 总成绩 6 0 3 请按任意键继续. . .  //这里是选择 4 成绩排序                         欢迎使用学生班级成绩管理系统！                 =============================================                 ==                主菜单                   ==                 =============================================                 ==              1.成绩录入                 ==                 ==              2.成绩显示                 ==                 ==              4.成绩排序                 ==                 ==              7.系统退出                 ==                 =============================================                 ===========请选择相应的功能列表============== 4 总成绩由低到高依次排序为： 0 3 6 请按任意键继续. . .  //这里是先选择 1.成绩录入 ，增加一个数10，然后选择2.成绩显示 ，10是最后加入的数字，在没有排序的时候 //它就是第一个，它就是表头。                       学生成绩表 ======================================================== 总成绩 10 0 3 6 请按任意键继续. . .   //这里是选择  4.成绩排序 。如果这时后接下去选择2.成绩显示，它就是显示已经排序好的排列了。                      学生成绩表 ======================================================== 总成绩 10 0 3 6 请按任意键继续. . .                         欢迎使用学生班级成绩管理系统！                 =============================================                 ==                主菜单                   ==                 =============================================                 ==              1.成绩录入                 ==                 ==              2.成绩显示                 ==                 ==              4.成绩排序                 ==                 ==              7.系统退出                 ==                 =============================================                 ===========请选择相应的功能列表============== 4 总成绩由低到高依次排序为： 0 3 6 10 请按任意键继续. . .

user: user-0
content: 引用 1 楼 user-1 的回复:楼主，这个链表是表头插入法，插入的最后一个节点就是表头，所以排序也是从最后一个开始的，而不是k=p->pNext 开始，修改如下见标注，供参考：#include<stdio.h> #include<conio.h> #include<stdlib.h> #include<string.h>  //定义一个学生的信息 typedef struct _Student {   int total;      //总成绩 }Student;  //定义一个节点 typedef struct _Node {    Student stu;//学生    struct _Node* pNext; }Node;  Node*g_pHead=NULL;             //头结点  void Menu();//菜单界面函数 void Input_m();//成绩录入函数 void Print();//成绩显示函数 void Save();//成绩保存函数 void Order();//成绩排序函数 void Modify();//成绩修改函数 void Sta();//声明成绩统计函数  int main() {     int a;     while(1){  //while循环使程序持续运行              Menu();              scanf("%d",&a);              switch(a)//**用户进行选择**//                    {                       case 1:                            Input_m(); //成绩录入                            break;                       case 2:                            Print();//成绩显示                            break;                       case 4:                            Order();//成绩排序                            break;                       case 7:                           printf("您已成功退出系统，欢迎下次使用！\n");                           return 0;                      default:                           printf("无效选择，请重新输入\n");                           system("pause");                           system("cls");                           break;              }     }     return 0; }  void Menu()//菜单界面函数  {         printf("\t\t\t欢迎使用学生班级成绩管理系统！\n");         printf("\t\t=============================================\n");         printf("\t\t==\t          主菜单                   ==\n");         printf("\t\t=============================================\n");         printf("\t\t==\t\t1.成绩录入                 ==\n");         printf("\t\t==\t\t2.成绩显示                 ==\n");         printf("\t\t==\t\t4.成绩排序                 ==\n");         printf("\t\t==\t\t7.系统退出                 ==\n");         printf("\t\t=============================================\n");         printf("\t\t===========请选择相应的功能列表==============\n");      } void Input_m()//成绩录入函数 {     Node* pNewNode =(Node*)malloc(sizeof(Node));//创建一个新节点     pNewNode->pNext=NULL;     if(g_pHead==NULL)       {         g_pHead=pNewNode;       }     else       {         pNewNode->pNext=g_pHead;         g_pHead=pNewNode;       }     printf("请输入学生的总成绩：\n");     scanf("%d",&pNewNode->stu.total);     printf("学生成绩录入成功！\n");     system("pause");      //暂停执行     system("cls");        //清屏 }  void Print()//成绩显示函数  {     system("cls");     printf("                     学生成绩表                         \n");     printf("========================================================\n");     printf("总成绩\n");      //遍历链表，一次打印出学生的成绩     Node* p=g_pHead;     while(p!=NULL)      {         printf("%d \n",p->stu.total);         p=p->pNext;//指向下一个，少了这个会无限循环      }     system("pause"); }  int trival(Node*g_pHead) {     Node* p=g_pHead;     int i=0;     Node* w;     w = p;             //w=p->pNext ;  //这句修改     while(w!=NULL)     {       w=w->pNext ;       i++;     }     return i; }  void Order()//总成绩排序函数 {     Node* p=g_pHead;     Node* k,*q;     int n,i,j;     Student temp;     n=trival(g_pHead);                    //这句修改     for(i=0,k=p ;i<n-1;i++,k=k->pNext )   //for(i=0,k=p->pNext ;i<n-1;i++,k=k->pNext )       {         for(j=i+1,q=k->pNext; j<n ; q=q->pNext ,j++)           {               if(k->stu.total> q->stu.total )                 {                    temp=k->stu ;                    k->stu =q->stu ;                    q->stu =temp;                 }           }       }     printf("总成绩由低到高依次排序为：\n");     while(p!=NULL){          printf("%d\n",p->stu.total);          p=p->pNext;     }     system("pause");     system("cls"); }  按这个改完执行程序后原来的问题还是在的呀