鱼C论坛

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

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

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

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

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

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

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

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

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

  3. struct BOOK{
  4.         int num;
  5.         struct BOOK *next;
  6. };

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

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

  20. void printlist(struct BOOK *list) //第四步打印单链表
  21. {
  22.         struct BOOK *print;
  23.         print=list->next;
  24.         while(print!=NULL)
  25.         {
  26.                 printf("\n%d",print->num);
  27.                 print=print->next;
  28.         }
  29. }
复制代码


程序片段2:感觉问题主要在这里
  1. void insertnode(struct BOOK *list,int date)//第三步插入结点
  2. {
  3.         struct BOOK *current=NULL;//一定一定要 把这里初始化,不然程序执行不下去
  4.         struct BOOK *previous=NULL;
  5.         struct BOOK *intonode = createnode(date);
  6.         if(list->next==NULL)
  7.         {
  8.                 struct BOOK *intonode = createnode(date);
  9.             intonode->next=list->next;
  10.             list->next=intonode;
  11.         }
  12.         else
  13.         {
  14.              current=list->next;
  15.              previous=list;
  16.              while(current->num<date&&current!=NULL)
  17.                   {
  18.                           previous=current;
  19.                           current=current->next;
  20.                   }
  21.              previous->next=intonode;
  22.              intonode->next=current;
  23.     }
  24.        
  25. }
复制代码


程序片段3
  1. int main()
  2. {
  3.         struct BOOK *list=createlist();
  4.         int date;       
  5.         while(1)
  6.     {
  7.           scanf("%d",&date);
  8.           if(date!=0)
  9.              {
  10.                 insertnode(list,date);
  11.              }
  12.           else
  13.              {
  14.                       break;
  15.               }
  16.     }
  17.     printlist(list);
  18.         return 0;
  19. }
复制代码
最佳答案
2021-9-19 08:43:25
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. struct BOOK {
  4.     int num;
  5.     struct BOOK *next;
  6. };

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

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

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

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

  35. void printlist(struct BOOK *list) //第四步打印单链表
  36. {
  37.     struct BOOK *print;
  38.     print = list->next;
  39.     while (print != NULL) {
  40.         printf("\n%d", print->num);
  41.         print = print->next;
  42.     }
  43. }

  44. /*
  45. void insertnode(struct BOOK *list, int date) //第三步插入结点
  46. {
  47.     struct BOOK *current = NULL; //一定一定要 把这里初始化,不然程序执行不下去
  48.     struct BOOK *previous = NULL;
  49.     struct BOOK *intonode = createnode(date);
  50.     if (list->next == NULL) {
  51.         //struct BOOK *intonode = createnode(date);
  52.         intonode->next = list->next;
  53.         list->next = intonode;
  54.     } else {
  55.         current = list->next;
  56.         previous = list;
  57.         //while (current->num < date && current != NULL) {
  58.         while (current != NULL && current->num < date) {
  59.             previous = current;
  60.             current = current->next;
  61.         }
  62.         previous->next = intonode;
  63.         intonode->next = current;
  64.     }
  65. }
  66. */

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

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

  83. int main() {
  84.     struct BOOK *list = createlist();
  85.     int date;
  86.     while (1) {
  87.         scanf("%d", &date);
  88.         if (date != 0) {
  89.             insertnode(list, date);
  90.         } else {
  91.             break;
  92.         }
  93.     }
  94.     printlist(list);
  95.     free_list(list);
  96.     return 0;
  97. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

对不起劳烦各位看这么长一串代码,但是这节课已经折腾我2天了,我想搞懂
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

  3. struct BOOK {
  4.     int num;
  5.     struct BOOK *next;
  6. };

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

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

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

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

  35. void printlist(struct BOOK *list) //第四步打印单链表
  36. {
  37.     struct BOOK *print;
  38.     print = list->next;
  39.     while (print != NULL) {
  40.         printf("\n%d", print->num);
  41.         print = print->next;
  42.     }
  43. }

  44. /*
  45. void insertnode(struct BOOK *list, int date) //第三步插入结点
  46. {
  47.     struct BOOK *current = NULL; //一定一定要 把这里初始化,不然程序执行不下去
  48.     struct BOOK *previous = NULL;
  49.     struct BOOK *intonode = createnode(date);
  50.     if (list->next == NULL) {
  51.         //struct BOOK *intonode = createnode(date);
  52.         intonode->next = list->next;
  53.         list->next = intonode;
  54.     } else {
  55.         current = list->next;
  56.         previous = list;
  57.         //while (current->num < date && current != NULL) {
  58.         while (current != NULL && current->num < date) {
  59.             previous = current;
  60.             current = current->next;
  61.         }
  62.         previous->next = intonode;
  63.         intonode->next = current;
  64.     }
  65. }
  66. */

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

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

  83. int main() {
  84.     struct BOOK *list = createlist();
  85.     int date;
  86.     while (1) {
  87.         scanf("%d", &date);
  88.         if (date != 0) {
  89.             insertnode(list, date);
  90.         } else {
  91.             break;
  92.         }
  93.     }
  94.     printlist(list);
  95.     free_list(list);
  96.     return 0;
  97. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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


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


小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-19 11:03:26 From FishC Mobile | 显示全部楼层
感觉你学的已经很好了,写的代码出问题是很正常的,我写的代码也会出问题的,很正常
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-25 13:11

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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