开天辟地的卷毛 2022-06-29 07:05 采纳率: 83.7%
浏览 46
已结题

c语言链表排序只能一次一次排的问题

//main.c函数
#include "stdio.h"
#include "caozuo.h"
#pragma warning(disable:4996)
int main()
{
    STUDENT * SL=NULL;//学生信息链表 
    char xm[20]; 
    //菜单
    printf("    **************学生成绩管理系统**************\n");
    printf("        *1.添加学生信息                            *\n"); 
    printf("        *2.删除学生信息                            *\n"); 
    printf("        *3.修改学生信息                            *\n"); 
    printf("        *4.浏览学生信息                            *\n");
    printf("        *5.保存学生信息                            *\n");    
    printf("        *6.打开文件                                *\n");
    printf("        *7.排序学生信息(以手机号码)                *\n");
    printf("        *0.退出程序                                *\n");
    printf("    ********************************************\n");
    printf("                                                      \n");
    printf("请选择: "); 
    //等待用户的输入确认
    int M,T;
    char z;
    M=getchar();
    T=getchar();
    while(M!='0')
    {
        switch(M)
        {
            case '1':
                 SL=TianJia(SL);        
                  break;
            case '2':
                   printf("请输入要删除的学生信息:");
                   gets(xm);
                   SL=ShanChu(SL,xm);
                   break;
            case '3':
                   printf("请输入要修改的学生信息:");
                   gets(xm);
                   SL=XiuGai(SL,xm);
                   break;
            case '4':printf("进入浏览学生信息的界面。\n");
                    LiuLan(SL);
                    break;
            case '5':
                    BAOCUN(SL);
                    break; 
            case '6':
                    SL=DaKai(SL);
                    break;
            case '7':
                    sort(SL);
                    break;
            case '0':break; 
        } 
        //显示菜单
        printf("按任意键继续");
        getchar(); 
        system("cls");//本函数实现清屏的功能 
        printf("1.添加学生信息\n"); 
        printf("2.删除学生信息\n"); 
        printf("3.修改学生信息\n"); 
        printf("4.浏览学生信息\n"); 
        printf("5.保存学生信息\n"); 
        printf("6.打开文件\n");
        printf("7.排序学生信息\n");
        printf("0.退出程序\n"); 
        M=getchar();
        T=getchar();    
    }
}


//student.h头文件
typedef struct date
{
    int year;
    int month;
    int day;
}DATE;
//姓名、性别、民族、出生日期、班级、地址、手机号码、宿舍
typedef struct student
{
    char xm[20];
    char xb[10];
    char mz[15];
    DATE csrq;
    char bj[20];
    char dz[50];
    char sj[15];
    char ss[14];
    struct student *next;
}STUDENT;
struct student *head;


//caozuo.h
#include "stdio.h"
#include "student.h"
#include "stdlib.h"
#include "string.h"
#pragma warning(disable:4996)
/*
SL:学生信息组成的单链表
newStudent:需要加入进来的新的学生结点
*/
STUDENT* tianjiaxuesheng(STUDENT* SL, STUDENT* newStudent)
{
    STUDENT* p1, * p2;
    //判断链接  SL是否 为空。
    if (SL == NULL)
    {
        SL = newStudent;
        newStudent->next = NULL;//将新加入结点的指针域,设置为NULL 
    }
    else
    {
        //定位链表的最后一个结点 
        p1 = SL;//让p1指向链表 的第一个结点
        p2 = SL;
        while (p1)
        {
            p2 = p1;
            p1 = p1->next;
        };
        //当跳出while循环的时候,说明 p1已经指向链表的最后一个结点 
        p2->next = newStudent;
        newStudent->next = NULL;
    }
    return SL;
}
STUDENT* ShanChu(STUDENT* SL, char xm[])
{
    STUDENT* p1, * p2;
    p1 = SL;
    p2 = SL;
    //检查是否是首结点
    if (strcmp(p1->xm, xm) == 0)
    {
        p2 = p1->next;
        free(p1);
        return p2;
    }
    while (p1)
    {
        if (strcmp(p1->xm, xm) == 0)//姓名匹配成功,执行删除操作 
        {
            p2->next = p1->next;
            free(p1);
            break;
        }
        p2 = p1;
        p1 = p1->next;
    };
    return SL;
}
//对应菜单 添加  的函数 
STUDENT* TianJia(STUDENT* SL)
{
    STUDENT* pNew;
    pNew = (STUDENT*)malloc(sizeof(STUDENT));
    int year, month, day;
    DATE cs = { 1976,1,15 };
    char xm[20], mz[20], bj[20], dz[50], sj[15], ss[50];
    char xb[10];
    printf("请输入要添加的学生信息:\n");
    printf("姓名:");
    gets(xm);
    strcpy(pNew->xm, xm);
    printf("性别:");
    gets(xb);
    strcpy(pNew->xb, xb);
    printf("民族:");
    gets(mz);
    strcpy(pNew->mz, mz);
    printf("出生日期(year-month-day):");
    scanf("%d-%d-%d", &year, &month, &day);
    pNew->csrq.year = year; pNew->csrq.month = month; pNew->csrq.day = day;
    getchar();//吸收所按的回车键 
    printf("班级:");
    gets(bj);
    strcpy(pNew->bj, bj);
    printf("地址:");
    gets(dz);
    strcpy(pNew->dz, dz);
    printf("手机:");
    gets(sj);
    strcpy(pNew->sj, sj);
    printf("宿舍:");
    gets(ss);
    strcpy(pNew->ss, ss);
    pNew->next = NULL;

    SL = tianjiaxuesheng(SL, pNew);
    //printf("TianJia-SL:%s\n",SL->bj); 
    return;
}



void LiuLan(STUDENT* SL)
{
    printf("***学生信息浏览***\n");
    printf("序号\t姓名\t性别\t民族\t出生日期\t班级\t\t地址\t\t手机\t\t宿舍\n");
    STUDENT* p1, * p2;
    p1 = SL;
    int i = 1;
    while (p1)
    {
        printf("%d\t%s\t%s\t%s\t%d-%d-%d\t%s\t%s\t%s\t%s\n",i++,p1->xm, p1->xb, p1->mz, p1->csrq.year, p1->csrq.month, p1->csrq.day, p1->bj, p1->dz, p1->sj, p1->ss);
        p1 = p1->next;
    };
    return;
}
STUDENT* DaKai(STUDENT* SL)
{
    FILE* fp;
    STUDENT* p1, * p2;
    fp = fopen("student.dat", "rb");
    if (fp == NULL)
    {
        printf("文件打开失败\n");
        return;
    }
    while (1)
    {
        p1 = (STUDENT*)malloc(sizeof(STUDENT));
        fread(p1, sizeof(STUDENT), 1, fp);
        if (feof(fp))  break;//如果文件尾,则结束循环 
        SL = tianjiaxuesheng(SL, p1);
    }
    fclose(fp);
    return SL;
}
//修改指定姓名的学生信息 
STUDENT* XiuGai(STUDENT* SL, char xm[])
{
    STUDENT* p1, * p2;
    p1 = SL;
    p2 = SL;
    int k;
    char xmNew[20], xbNew[10], sjNew[15], bjNew[20], dzNew[50], ssNew[50], mzNew[20];
    int newyear, newmonth, newday;
    while (p1)
    {
        if (strcmp(p1->xm, xm) == 0)//姓名匹配成功,执行修改操作 
        {
            printf("请选择你要修改的数据字段:\n");
            printf("1.姓名\n");
            printf("2.民族\n");
            printf("3.性别\n");
            printf("4.出生日期\n");
            printf("5.班级\n");
            printf("6.地址\n");
            printf("7.手机\n");
            printf("8.宿舍\n");
            scanf("%d", &k);
            getchar();
            switch (k)
            {
            case 1:
                printf("请输入新的姓名:");
                gets(xmNew);
                strcpy(p1->xm, xmNew);
                break;
            case 2:
                printf("请输入新的民族:");
                gets(mzNew);
                strcpy(p1->mz, mzNew);
                break;
            case 3:
                printf("请输入新的性别(M/F):");
                gets(xbNew);
                strcpy(p1->xb, xbNew);
                break;
            case 4:printf("出生日期(year-month-day):");
                scanf("%d-%d-%d", &newyear, &newmonth, &newday);
                p1->csrq.year = newyear; p1->csrq.month = newmonth; p1->csrq.day = newday;
                getchar();
                break;
            case 5:
                printf("请输入新的班级:");
                gets(bjNew);
                strcpy(p1->bj, bjNew);
                break;
            case 6:printf("请输入新的地址:");
                gets(dzNew);
                strcpy(p1->dz, dzNew);
                break;
            case 7:printf("请输入新的手机:");
                gets(sjNew);
                strcpy(p1->sj, sjNew);
                break;
            case 8:printf("请输入新的宿舍:");
                gets(ssNew);
                strcpy(p1->ss, ssNew);
                break;
            }
        }
        p2 = p1;
        p1 = p1->next;
    };
    return SL;
}
void BAOCUN(STUDENT* SL)
{
    FILE* fp;
    STUDENT* p1, * p2;
    fp = fopen("student.dat", "wb");
    if (fp == NULL)
    {
        printf("文件打开失败,无法保存学生信息。\n");
        return;
    }
    p1 = SL;//让p1指向链表 的第一个结点
    while (p1)
    {
        p2 = p1;
        //将 p2所指向的结点数据,写入文件 fp
        fwrite(p2, sizeof(STUDENT), 1, fp);
        p1 = p1->next;
    };

    fclose(fp);
}
void* sort(STUDENT* SL)
{
    //插入排序
    head = (struct student*)malloc(sizeof(struct student));
    head = SL; //把链表第一个结点赋给head 

    struct student* p = head, * q, * tail;
    int i, j, num = 0;
    while (p->next)
    {
        p = p->next;
        num++;
    }
    for (i = 0; i < num - 1; i++)
    {
        p = head;
        q = p->next;
        tail = q->next;
        num = num - i - 1;
        while (num!=0)
        {
            if (strcmp(tail->sj, q->sj))
            {
                q->next = tail->next;
                tail->next = q;
                p->next = tail;
                num--;
            }
            p = p->next;
            q = p->next;
            tail = q->next;
        }
    }
    printf("链表排序完成!\n");
}

如图,三个文件是学生信息管理系统链表,想问一下,我在使用caozuo.h中的sort排序功能时,只能实现运行一次,排序一次的情况,假如假如40个数据,运行一次,就将第二个结点和第三个结点判断。如何可以运行一次,就把整一个链表排序?

  • 写回答

1条回答 默认 最新

  • it_hao528 2022-06-29 10:43
    关注

    出现排序一次的原因:
    for循环进入循环条件num在减for循环中减小,并且在while循环中也在减小,且while循环结束后num=0,for循环i=1>num将退出循环。
    解决:
    1、删除346行的num = num - i - 1;
    2、修改347行的while(num != 0) 为 while(tail != NULL)
    3、删除354行的num--;

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 7月7日
  • 已采纳回答 6月29日
  • 创建了问题 6月29日

悬赏问题

  • ¥15 滑块验证码移动速度不一致问题
  • ¥15 定制ai直播实时换脸软件
  • ¥100 栈回溯相关,模块加载后KiExceptionDispatch无法正常回溯了
  • ¥15 Utunbu中vscode下cern root工作台中写的程序root的头文件无法包含
  • ¥15 麒麟V10桌面版SP1如何配置bonding
  • ¥15 Marscode IDE 如何预览新建的 HTML 文件
  • ¥15 K8S部署二进制集群过程中calico一直报错
  • ¥15 java python或者任何一种编程语言复刻一个网页
  • ¥20 如何通过代码传输视频到亚马逊平台
  • ¥15 php查询mysql数据库并显示至下拉列表中