鱼C论坛

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

[已解决]链表问题

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

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

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

x
这是个创建链表和删除节点的程序,基本功能没问题,但是当我测试程序时,第一个节点就输入0时,我的删除节点函数void del(struct student *q,int num1)直接报错,里面的条件判断
if(q1->num==0) printf("空表无法执行!");起不了作用。


  1. #include <stdio.h>
  2. #include <malloc.h>


  3. struct student
  4. {
  5.         int num;
  6.         float score;
  7.         struct student *next;//结构体变量成员指针,用于存放下一个节点的地址
  8. };

  9. int n;

  10. int main(void)
  11. {
  12.         struct student *creat();
  13.         void print(struct student *r);
  14.         void del(struct student *q,int num1);

  15.         int m;
  16.         struct student *stu;

  17.         stu=creat();//返回链表头节点
  18.         printf("\nThere are %d record!\n\n",n);
  19.         print(stu);//输出所有节点

  20.         printf("请输入你想删除的学生的编号:");
  21.         scanf("%d",&m);
  22.         printf("\n\n");
  23.         del(stu,m);

  24.         printf("\n\n");
  25. }

  26. struct student *creat()
  27. {
  28.         struct student *p1,*p2,*head;
  29.         n=0;
  30.         head=NULL;
  31.         p2=(struct student *)malloc(sizeof(struct student));
  32.         while(1)
  33.         {
  34.                 p1=(struct student *)malloc(sizeof(struct student));
  35.                 printf("Please enter this student number:");
  36.                 scanf("%d",&p1->num);
  37.                 printf("Please enter this student score:");
  38.                 scanf("%f",&p1->score);
  39.                 if(0==p1->num)
  40.                 {
  41.                         break;
  42.                 }
  43.                 else
  44.                 {
  45.                         n++;
  46.                         if(1==n)
  47.                         {
  48.                                 head=p1;
  49.                                 p2=p1;
  50.                         }
  51.                         else
  52.                         {
  53.                                 p2->next=p1;
  54.                                 p2=p1;
  55.                         }
  56.                 }               
  57. }
  58.         p2->next=NULL;

  59.         return head;
  60. }

  61. void print(struct student *r)
  62. {
  63.        
  64.         while(r)//当q运行至链尾,自动停止
  65.         {
  66.                 printf("第 %d 位学生的成绩是 %.1f\n",r->num,r->score);
  67.                 r=r->next;
  68.         }
  69.         printf("\n");
  70. }

  71. void del(struct student *q,int num1)
  72. {
  73.         void print(struct student *r);

  74.         struct student *q1,*q2;
  75.         q1=q;
  76.         if(q1->num==0)
  77.         {
  78.                 printf("空表无法执行!");
  79.         }
  80.         else
  81.         {
  82.                 if(num1==q1->num)
  83.                 {
  84.                         q=q->next;
  85.                 }
  86.                 else
  87.                 {
  88.                         while(1)
  89.                         {
  90.                                 if(num1!=q1->num)
  91.                                 {
  92.                                         q2=q1;
  93.                                         q1=q1->next;
  94.                                 }
  95.                                 else if(num1==q1->num)
  96.                                 {
  97.                                         q2->next=q1->next;
  98.                                         q1->next=NULL;
  99.                                         break;
  100.                                 }
  101.                         }
  102.                 }
  103.         }
  104.         print(q);
  105. }
复制代码
最佳答案
2021-1-21 14:08:50
        始终把被调用的函数放在调用函数的前面就可以避免对函数的声明。就像下面这样,把 main() 放在最后。
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. struct student
  4. {
  5.         int num;
  6.         float score;
  7.         struct student *next;//结构体变量成员指针,用于存放下一个节点的地址
  8. };

  9. int n;

  10. void print(struct student *r)
  11. {
  12.         for(; r ; r = r -> next) printf("学号: %d , 成绩 : %.1f\n" , r -> num , r -> score) ;
  13.         printf("\n")                                                                        ;
  14. }

  15. struct student *creat()
  16. {
  17.         struct student *p1,*p2,*head;
  18.         n=0;
  19.         head=NULL;
  20.         p2=(struct student *)malloc(sizeof(struct student));
  21.         while(1)
  22.         {
  23.                 p1=(struct student *)malloc(sizeof(struct student));
  24.                 printf("Please enter this student number:");
  25.                 scanf("%d",&p1->num);
  26.                 printf("Please enter this student score:");
  27.                 scanf("%f",&p1->score);
  28.                 if(0==p1->num)
  29.                 {
  30.                         break;
  31.                 }
  32.                 else
  33.                 {
  34.                         n++;
  35.                         if(1==n)
  36.                         {
  37.                                 head=p1;
  38.                                 p2=p1;
  39.                         }
  40.                         else
  41.                         {
  42.                                 p2->next=p1;
  43.                                 p2=p1;
  44.                         }
  45.                 }               
  46. }
  47.         p2->next=NULL;

  48.         return head;
  49. }

  50. struct student * del(struct student * q , int num1)
  51. {
  52.         struct student * h , * q1 , * q2                                                   ;
  53.         if(q) {
  54.                 for(h = q1 = q2 = q ; q1 && q1 -> num != num1 ; q2 = q1 , q1 = q2 -> next) ;
  55.                 if(q1) {
  56.                         if(q1 == q2) h = q1 -> next                                        ; // 将要被删除的是头节点
  57.                         else q2 -> next = q1 -> next                                       ; // 将要被删除的是内部节点
  58.                         free(q1)                                                           ; // 释放节点占用内存
  59.                         print(h)                                                           ; // 只是在删除成功的时候才打印新的链表
  60.                 } else {
  61.                         printf("抱歉,节点未找到。\n")                                     ;
  62.                 }
  63.         } else {
  64.                 printf("抱歉,链表为空,无法操作。\n")                                     ;
  65.         }
  66.         return h                                                                           ; // 头节点有可能被删除,所以,必须返回新的头节点
  67. }

  68. int main(void)
  69. {
  70.         int m                                  ;
  71.         struct student * stu = NULL            ;
  72.         stu = creat()                          ; // 返回链表头节点
  73.         printf("\nThere are %d record!\n\n",n) ;
  74.         print(stu)                             ; // 输出所有节点
  75.         printf("请输入你想删除的学生的编号:") ;
  76.         scanf("%d" , & m)                      ;
  77.         printf("\n\n")                         ;
  78.         stu = del(stu , m)                     ;
  79.         printf("\n\n")                         ;
  80. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-1-21 12:32:33 | 显示全部楼层
       你还是先把前面的求助帖结了吧。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-1-21 13:04:19 | 显示全部楼层
jackz007 发表于 2021-1-21 12:32
你还是先把前面的求助帖结了吧。

哈哈哈,好了,搞忘了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-1-21 14:08:50 | 显示全部楼层    本楼为最佳答案   
        始终把被调用的函数放在调用函数的前面就可以避免对函数的声明。就像下面这样,把 main() 放在最后。
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. struct student
  4. {
  5.         int num;
  6.         float score;
  7.         struct student *next;//结构体变量成员指针,用于存放下一个节点的地址
  8. };

  9. int n;

  10. void print(struct student *r)
  11. {
  12.         for(; r ; r = r -> next) printf("学号: %d , 成绩 : %.1f\n" , r -> num , r -> score) ;
  13.         printf("\n")                                                                        ;
  14. }

  15. struct student *creat()
  16. {
  17.         struct student *p1,*p2,*head;
  18.         n=0;
  19.         head=NULL;
  20.         p2=(struct student *)malloc(sizeof(struct student));
  21.         while(1)
  22.         {
  23.                 p1=(struct student *)malloc(sizeof(struct student));
  24.                 printf("Please enter this student number:");
  25.                 scanf("%d",&p1->num);
  26.                 printf("Please enter this student score:");
  27.                 scanf("%f",&p1->score);
  28.                 if(0==p1->num)
  29.                 {
  30.                         break;
  31.                 }
  32.                 else
  33.                 {
  34.                         n++;
  35.                         if(1==n)
  36.                         {
  37.                                 head=p1;
  38.                                 p2=p1;
  39.                         }
  40.                         else
  41.                         {
  42.                                 p2->next=p1;
  43.                                 p2=p1;
  44.                         }
  45.                 }               
  46. }
  47.         p2->next=NULL;

  48.         return head;
  49. }

  50. struct student * del(struct student * q , int num1)
  51. {
  52.         struct student * h , * q1 , * q2                                                   ;
  53.         if(q) {
  54.                 for(h = q1 = q2 = q ; q1 && q1 -> num != num1 ; q2 = q1 , q1 = q2 -> next) ;
  55.                 if(q1) {
  56.                         if(q1 == q2) h = q1 -> next                                        ; // 将要被删除的是头节点
  57.                         else q2 -> next = q1 -> next                                       ; // 将要被删除的是内部节点
  58.                         free(q1)                                                           ; // 释放节点占用内存
  59.                         print(h)                                                           ; // 只是在删除成功的时候才打印新的链表
  60.                 } else {
  61.                         printf("抱歉,节点未找到。\n")                                     ;
  62.                 }
  63.         } else {
  64.                 printf("抱歉,链表为空,无法操作。\n")                                     ;
  65.         }
  66.         return h                                                                           ; // 头节点有可能被删除,所以,必须返回新的头节点
  67. }

  68. int main(void)
  69. {
  70.         int m                                  ;
  71.         struct student * stu = NULL            ;
  72.         stu = creat()                          ; // 返回链表头节点
  73.         printf("\nThere are %d record!\n\n",n) ;
  74.         print(stu)                             ; // 输出所有节点
  75.         printf("请输入你想删除的学生的编号:") ;
  76.         scanf("%d" , & m)                      ;
  77.         printf("\n\n")                         ;
  78.         stu = del(stu , m)                     ;
  79.         printf("\n\n")                         ;
  80. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-1-21 14:45:02 | 显示全部楼层
jackz007 发表于 2021-1-21 14:08
始终把被调用的函数放在调用函数的前面就可以避免对函数的声明。就像下面这样,把 main() 放在最后 ...

哦,明白了,这里q调用的是头节点,如果用户输入0,head是没有被改变的,依然是NULL,直接用头节点进行条件判断,排除空表。行,谢谢大佬
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-5-2 12:06

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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