鱼C论坛

 找回密码
 立即注册
查看: 953|回复: 14

[已解决]请教关于链表冒泡排序的问题

[复制链接]
发表于 2020-5-11 00:00:36 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
编译没问题,调试有问题,新手暂时看不懂反汇编的调用堆栈,想知道哪里有错
最佳答案
2020-5-11 11:10:17
本帖最后由 赚小钱 于 2020-5-11 11:14 编辑

1. 为什么这么复杂,应该和数组的冒泡排序长得一样啊。 交换两个节点的数据他不香吗,非要交换节点本身。

2. 请科学设计变量名。

3. 单步调试可以使用打断点,watch 一个变量的变化等高级功能。如果是命令行,不会用 gdb 等工具,可以使用 print 大法。

4. 不清楚你说的那一行有问题是什么类型的问题。 https://github.com/FredWe/How-To-Ask-Questions-The-Smart-Way
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-5-11 00:02:15 | 显示全部楼层
附上相关代码
struct STU
{
        char stunum[10];
        char stuname[20];
        int stuage;
};

struct Node
{
        struct STU data;
        struct Node* next;
};
void bubbleSortListByNum(struct Node* headNode)//冒泡排序法,按学号升序
{
        struct  Node* p1, *p2, *p3, *p4,*p5,*pMove;
        p1 = p3= p5=headNode;
        p2 = headNode->next;
        while (p3->next!=NULL)
        {
                if (p1->data.stunum >= p2->data.stunum)
                {
                        p1->next = p2->next;
                        p2->next = p1;
                        p2 = p1->next;
                }
                else
                {
                        p1 = p1->next;
                        p2 = p2->next;
                }
                p4 = p2->next;
                while (p4->next != NULL)//这一行调试有问题
                {
                        if (p1->data.stunum >= p2->data.stunum)
                        {
                                p1->next = p2->next;
                                p2->next = p1;
                                p2 = p1->next;
                        }
                        else
                        {
                                p1 = p1->next;
                                p2 = p2->next;
                        }
                        p4 = p2->next;
                }
                p3 = p3->next;
                p1 = p3;
                p2 = p1->next;
        }
        pMove = p5->next;//打印排序后的结果
        while (pMove)
        {
                printf("%s\t%s\t\t%d\n", pMove->data.stunum, pMove->data.stuname, pMove->data.stuage);
                pMove = pMove->next;
        }
        printf("\n");
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-11 09:33:14 | 显示全部楼层
给你说个思路,排序函数里定义个临时结构体,交换时交换结构体,这样就不用指针变来变去把自己都搞晕了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-11 09:50:12 | 显示全部楼层
发完整的代码,我不喜欢盯着代码找bug,而是让程序运行起来,让编译器或调试器捕获bug
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-5-11 10:21:05 | 显示全部楼层
人造人 发表于 2020-5-11 09:50
发完整的代码,我不喜欢盯着代码找bug,而是让程序运行起来,让编译器或调试器捕获bug

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//学生结构
struct STU
{
        char stunum[10];
        char stuname[20];
        int stuage;
};
//把所有要处理的数据改为我们的数据
struct Node
{
        struct STU data;
        struct Node* next;
};
//创建一个表头
struct Node* creatList()
{
        struct Node* headNode = (struct Node*)malloc(sizeof(struct Node));
        headNode->next = NULL;
        return headNode;
};
//创建节点
struct Node* createNode(struct STU data)
{
        struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
        newNode->next = NULL;
        newNode->data = data;
        return newNode;
};
void insertNodeByHead(struct Node* headNode, struct STU data)
{
        struct  Node* newNode = createNode(data);
        newNode->next = headNode->next;
        headNode->next = newNode;

}
void bubbleSortListByNum(struct Node* headNode)//冒泡排序法,按学号升序这个有待调试
{

        struct  Node* p1, *p2, *p3, *p4, *p5, *pMove;
        p1 = p3= p5=headNode;
        p2 = headNode->next;
        p4 = NULL;
        while (p3->next!=NULL)
        {
                if (p1->data.stunum > p2->data.stunum)
                {
                        p1->next = p2->next;
                        p2->next = p1;
                        p2 = p1->next;
                }
                else
                {
                        p1 = p1->next;
                        p2 = p2->next;
                }
                p4 = p2;
                while (p4->data.stunum)
                {
                        if (p1->data.stunum > p2->data.stunum)
                        {
                                p1->next = p2->next;
                                p2->next = p1;
                                p2 = p1->next;
                        }
                        else
                        {
                                p1 = p1->next;
                                p2 = p2->next;
                        }
                        p4 = p4->next;
                }
                p3 = p3->next;
                p1 = p3;
                p2 = p3->next;
        }
        pMove = p5->next;//打印排序后的结果
        while (pMove)
        {
                printf("%s\t%s\t\t%d\n", pMove->data.stunum, pMove->data.stuname, pMove->data.stuage);
                pMove = pMove->next;
        }
        printf("\n");
}
//读文件
void readInfoFromFile(struct Node* list, char *filename)//打开文件
{
        FILE *fp = fopen(filename, "r");
        if (fp == NULL)
        {
                fp = fopen(filename, "w+");
        }
        struct STU tempInfo;
        while (fscanf(fp, "%s\t%s\t%d\n", tempInfo.stunum, tempInfo.stuname, &tempInfo.stuage) != EOF)
        {
                insertNodeByHead(list, tempInfo);
        }
        fclose(fp);
}
void saveInfoToFile(struct Node* headNode, char *filename)//编辑并保存文件
{
        FILE *fp = fopen(filename, "w");
        struct Node* pMove = headNode->next;
        while (pMove)
        {
                fprintf(fp, "%s\t%s\t%d\n", pMove->data.stunum, pMove->data.stuname, pMove->data.stuage);
                pMove = pMove->next;
        }
        fclose(fp);
}
struct Node* list = NULL;
void drawMenu()
{
        printf("                                欢迎进入数据系统\n");
        printf("                0.退出系统\n");
        printf("                1.录入信息\n");
        printf("                2.按照学号冒泡排序\n");
        printf("                请输入0—2:");

}
void keyDown()
{
        int userKey = 0;
        struct STU stu;
        struct Node* posNode = NULL;
        scanf("%d", &userKey);
        switch (userKey)
        {
        case 0:
                printf("已退出\n");
                system("pause");
                exit(0);
                break;
        case 1:
                printf("                录入学生信息\n");
                printf("                请输入:stunum,name,stuage(以空格隔开):");
                scanf("%s%s%d", stu.stunum, stu.stuname, &stu.stuage);
                insertNodeByHead(list, stu);
                saveInfoToFile(list, "student.txt");
                break;
        case 2:
                printf("                排序结果\n");
                bubbleSortListByNum(list);
                break;
        default:
                printf("                输入错误,请重新输入\n");
        }
}
int main()
{
        list = creatList();
        readInfoFromFile(list, "student.txt");
        while (true)
        {
                drawMenu();
                keyDown();
                system("pause");
                system("cls");//清屏
        }
        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-11 11:10:17 | 显示全部楼层    本楼为最佳答案   
本帖最后由 赚小钱 于 2020-5-11 11:14 编辑

1. 为什么这么复杂,应该和数组的冒泡排序长得一样啊。 交换两个节点的数据他不香吗,非要交换节点本身。

2. 请科学设计变量名。

3. 单步调试可以使用打断点,watch 一个变量的变化等高级功能。如果是命令行,不会用 gdb 等工具,可以使用 print 大法。

4. 不清楚你说的那一行有问题是什么类型的问题。 https://github.com/FredWe/How-To-Ask-Questions-The-Smart-Way
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-11 12:36:54 | 显示全部楼层
address of array 'p4->data.stunum' will always evaluate to 'true'
1.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-11 12:39:26 | 显示全部楼层
1.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-11 12:43:24 | 显示全部楼层
while (p4->next != NULL)//这一行调试有问题

你输入了什么?然后在这里出现了问题
我需要知道你输入了什么,这样我才能在我这边输入相同的内容,才能在这一行出问题,才能让调试器捕获这个问题
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-5-11 15:41:59 | 显示全部楼层
本帖最后由 zqdlly 于 2020-5-11 15:46 编辑
人造人 发表于 2020-5-11 12:43
你输入了什么?然后在这里出现了问题
我需要知道你输入了什么,这样我才能在我这边输入相同的内容,才 ...


输入的信息是任意的,只是按照学号进行排序,学号随便填个八位数就行
95271234        促进        89
00000000        了        0
18170001        张三        19
12345678        测试        0
99999999        福建        78
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-11 15:50:59 | 显示全部楼层
zqdlly 发表于 2020-5-11 15:41
输入的信息是任意的,只是按照学号进行排序,学号随便填个八位数就行
95271234        促进        89
00000000        了         ...

第一幅图是怎么回事?
这个
address of array 'p4->data.stunum' will always evaluate to 'true'
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-5-11 16:04:48 | 显示全部楼层
人造人 发表于 2020-5-11 15:50
第一幅图是怎么回事?
这个

谢谢,我去调试下啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-5-11 16:12:18 | 显示全部楼层
赚小钱 发表于 2020-5-11 11:10
1. 为什么这么复杂,应该和数组的冒泡排序长得一样啊。 交换两个节点的数据他不香吗,非要交换节点本身。
...

谢谢,忘记了可以用printf调试了,自己先去看看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-5-11 16:22:25 | 显示全部楼层
赚小钱 发表于 2020-5-11 11:10
1. 为什么这么复杂,应该和数组的冒泡排序长得一样啊。 交换两个节点的数据他不香吗,非要交换节点本身。
...

感谢高人指点,仅凭您提出的1.3两条就解决的差不多了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-11 16:29:08 | 显示全部楼层
zqdlly 发表于 2020-5-11 16:22
感谢高人指点,仅凭您提出的1.3两条就解决的差不多了

兄弟觉得满意,就给咱一个最佳答案呗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-14 01:20

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表