鱼C论坛

 找回密码
 立即注册
查看: 2024|回复: 4

[已解决]单链表插入搞了个奇怪的bug实在不知道怎么搞

[复制链接]
发表于 2021-9-19 00:54:21 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 GmiaoC 于 2021-9-19 01:15 编辑

小甲鱼的带飞C第47课                  “用单链表随机输入一些整数进去,然后从小到大的方式排列出来“         
看着小甲鱼的二重头指针感到有点头疼,于是自己用模块化的形式写了出来,算是成功实现了一大半,就是有个奇怪的BUG:

当输入了第一个整数之后,后面再输入的整数无论如何都不能大于第一个输入的整数,不然就报错

实在想不懂这个bug怎么出来的,求大佬们指点指点,感觉问题主要在程序片段2
程序片段1:
#include<stdio.h>
#include<stdlib.h>

struct BOOK{
        int num;
        struct BOOK *next;
};

struct BOOK *createlist()     //这是第一步一个创建链表的函数 
{
        struct BOOK *list=(struct BOOK *)malloc(sizeof(struct BOOK));
        list->next=NULL;
        return list;     //返回了一个指针 
}

struct BOOK *createnode(int date) //第二步创建一个新的结点只需要数据
{
     struct BOOK *newnode=(struct BOOK *)malloc(sizeof(struct BOOK));
     newnode->num=date;
     newnode->next=NULL;
     return newnode;//返回一个指针 
}

void printlist(struct BOOK *list) //第四步打印单链表
{
        struct BOOK *print;
        print=list->next;
        while(print!=NULL)
        {
                printf("\n%d",print->num);
                print=print->next;
        }
}

程序片段2:感觉问题主要在这里
void insertnode(struct BOOK *list,int date)//第三步插入结点 
{
        struct BOOK *current=NULL;//一定一定要 把这里初始化,不然程序执行不下去 
        struct BOOK *previous=NULL;
        struct BOOK *intonode = createnode(date);
        if(list->next==NULL)
        {
                struct BOOK *intonode = createnode(date);
            intonode->next=list->next;
            list->next=intonode;
        }
        else
        {
             current=list->next;
             previous=list;
             while(current->num<date&¤t!=NULL)
                  {
                          previous=current;
                          current=current->next;
                  }
             previous->next=intonode;
             intonode->next=current;
    }
        
}

程序片段3
int main()
{
        struct BOOK *list=createlist();
        int date;        
        while(1)
    {
          scanf("%d",&date);
          if(date!=0)
             {
                insertnode(list,date);
             }
          else
             {
                      break;
              }
    }
    printlist(list);
        return 0;
}
最佳答案
2021-9-19 08:43:25
#include <stdio.h>
#include <stdlib.h>

struct BOOK {
    int num;
    struct BOOK *next;
};

// 下面这两个函数没有错,但是写的不好
// 换一下位置,createlist 直接调用 createnode
/*
struct BOOK *createlist() //这是第一步一个创建链表的函数
{
    struct BOOK *list = (struct BOOK *)malloc(sizeof(struct BOOK));
    list->next = NULL;
    return list; //返回了一个指针
}

struct BOOK *createnode(int date) //第二步创建一个新的结点只需要数据
{
    struct BOOK *newnode = (struct BOOK *)malloc(sizeof(struct BOOK));
    newnode->num = date;
    newnode->next = NULL;
    return newnode; //返回一个指针
}
*/

struct BOOK *createnode(int date) //第二步创建一个新的结点只需要数据
{
    struct BOOK *newnode = (struct BOOK *)malloc(sizeof(struct BOOK));
    newnode->num = date;
    newnode->next = NULL;
    return newnode; //返回一个指针
}

struct BOOK *createlist() //这是第一步一个创建链表的函数
{
    return createnode(0);
}

void printlist(struct BOOK *list) //第四步打印单链表
{
    struct BOOK *print;
    print = list->next;
    while (print != NULL) {
        printf("\n%d", print->num);
        print = print->next;
    }
}

/*
void insertnode(struct BOOK *list, int date) //第三步插入结点
{
    struct BOOK *current = NULL; //一定一定要 把这里初始化,不然程序执行不下去
    struct BOOK *previous = NULL;
    struct BOOK *intonode = createnode(date);
    if (list->next == NULL) {
        //struct BOOK *intonode = createnode(date);
        intonode->next = list->next;
        list->next = intonode;
    } else {
        current = list->next;
        previous = list;
        //while (current->num < date && current != NULL) {
        while (current != NULL && current->num < date) {
            previous = current;
            current = current->next;
        }
        previous->next = intonode;
        intonode->next = current;
    }
}
*/

// 上面的已经改好了,能用了,但是不好,下面这样不知道你能不能看懂
void insertnode(struct BOOK *list, int date) {
    struct BOOK **current = &list->next;
    while(*current != NULL && (*current)->num < date) {
        current = &(*current)->next;
    }
    struct BOOK *temp = createnode(date);
    temp->next = *current;
    *current = temp;
}

// 申请了内存一定要释放,你那边可能没问题,但是我这边会报错的
// 对,你没有看错,申请了内存不释放,我这边是会报错的
void free_list(struct BOOK *list) {
    if(list) free_list(list->next);
    free(list);
}

int main() {
    struct BOOK *list = createlist();
    int date;
    while (1) {
        scanf("%d", &date);
        if (date != 0) {
            insertnode(list, date);
        } else {
            break;
        }
    }
    printlist(list);
    free_list(list);
    return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-9-19 00:57:21 | 显示全部楼层
本帖最后由 GmiaoC 于 2021-9-19 01:16 编辑

对不起劳烦各位看这么长一串代码,但是这节课已经折腾我2天了,我想搞懂
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-19 08:43:25 | 显示全部楼层    本楼为最佳答案   
#include <stdio.h>
#include <stdlib.h>

struct BOOK {
    int num;
    struct BOOK *next;
};

// 下面这两个函数没有错,但是写的不好
// 换一下位置,createlist 直接调用 createnode
/*
struct BOOK *createlist() //这是第一步一个创建链表的函数
{
    struct BOOK *list = (struct BOOK *)malloc(sizeof(struct BOOK));
    list->next = NULL;
    return list; //返回了一个指针
}

struct BOOK *createnode(int date) //第二步创建一个新的结点只需要数据
{
    struct BOOK *newnode = (struct BOOK *)malloc(sizeof(struct BOOK));
    newnode->num = date;
    newnode->next = NULL;
    return newnode; //返回一个指针
}
*/

struct BOOK *createnode(int date) //第二步创建一个新的结点只需要数据
{
    struct BOOK *newnode = (struct BOOK *)malloc(sizeof(struct BOOK));
    newnode->num = date;
    newnode->next = NULL;
    return newnode; //返回一个指针
}

struct BOOK *createlist() //这是第一步一个创建链表的函数
{
    return createnode(0);
}

void printlist(struct BOOK *list) //第四步打印单链表
{
    struct BOOK *print;
    print = list->next;
    while (print != NULL) {
        printf("\n%d", print->num);
        print = print->next;
    }
}

/*
void insertnode(struct BOOK *list, int date) //第三步插入结点
{
    struct BOOK *current = NULL; //一定一定要 把这里初始化,不然程序执行不下去
    struct BOOK *previous = NULL;
    struct BOOK *intonode = createnode(date);
    if (list->next == NULL) {
        //struct BOOK *intonode = createnode(date);
        intonode->next = list->next;
        list->next = intonode;
    } else {
        current = list->next;
        previous = list;
        //while (current->num < date && current != NULL) {
        while (current != NULL && current->num < date) {
            previous = current;
            current = current->next;
        }
        previous->next = intonode;
        intonode->next = current;
    }
}
*/

// 上面的已经改好了,能用了,但是不好,下面这样不知道你能不能看懂
void insertnode(struct BOOK *list, int date) {
    struct BOOK **current = &list->next;
    while(*current != NULL && (*current)->num < date) {
        current = &(*current)->next;
    }
    struct BOOK *temp = createnode(date);
    temp->next = *current;
    *current = temp;
}

// 申请了内存一定要释放,你那边可能没问题,但是我这边会报错的
// 对,你没有看错,申请了内存不释放,我这边是会报错的
void free_list(struct BOOK *list) {
    if(list) free_list(list->next);
    free(list);
}

int main() {
    struct BOOK *list = createlist();
    int date;
    while (1) {
        scanf("%d", &date);
        if (date != 0) {
            insertnode(list, date);
        } else {
            break;
        }
    }
    printlist(list);
    free_list(list);
    return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-9-19 09:41:44 | 显示全部楼层


我擦,为什么???仅仅只是改动了&&的先后顺序就解决了,是我逻辑的基础哪里没有学好吗。
先感谢大佬,虽然后面改动使用指针的指针也看的懂,但是我初学怕用得不好所以没这么写
//current->num<date&¤t!=NULL 就是这个顺序出现了bug
current!=NULL&¤t->num<date

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-19 11:03:26 From FishC Mobile | 显示全部楼层
感觉你学的已经很好了,写的代码出问题是很正常的,我写的代码也会出问题的,很正常
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-6 18:00

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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