GmiaoC 发表于 2021-9-19 00:54:21

单链表插入搞了个奇怪的bug实在不知道怎么搞

本帖最后由 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&&current!=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;
}

GmiaoC 发表于 2021-9-19 00:57:21

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

{:10_269:}对不起劳烦各位看这么长一串代码,但是这节课已经折腾我2天了,我想搞懂

人造人 发表于 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;
}

GmiaoC 发表于 2021-9-19 09:41:44

人造人 发表于 2021-9-19 08:43


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

人造人 发表于 2021-9-19 11:03:26

感觉你学的已经很好了,写的代码出问题是很正常的,我写的代码也会出问题的,很正常
页: [1]
查看完整版本: 单链表插入搞了个奇怪的bug实在不知道怎么搞