MeowMoo 发表于 2021-1-21 10:48:00

链表问题

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


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


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

int n;

int main(void)
{
        struct student *creat();
        void print(struct student *r);
        void del(struct student *q,int num1);

        int m;
        struct student *stu;

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

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

        printf("\n\n");
}

struct student *creat()
{
        struct student *p1,*p2,*head;
        n=0;
        head=NULL;
        p2=(struct student *)malloc(sizeof(struct student));
        while(1)
        {
                p1=(struct student *)malloc(sizeof(struct student));
                printf("Please enter this student number:");
                scanf("%d",&p1->num);
                printf("Please enter this student score:");
                scanf("%f",&p1->score);
                if(0==p1->num)
                {
                        break;
                }
                else
                {
                        n++;
                        if(1==n)
                        {
                                head=p1;
                                p2=p1;
                        }
                        else
                        {
                                p2->next=p1;
                                p2=p1;
                        }
                }               
}
        p2->next=NULL;

        return head;
}

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

void del(struct student *q,int num1)
{
        void print(struct student *r);

        struct student *q1,*q2;
        q1=q;
        if(q1->num==0)
        {
                printf("空表无法执行!");
        }
        else
        {
                if(num1==q1->num)
                {
                        q=q->next;
                }
                else
                {
                        while(1)
                        {
                                if(num1!=q1->num)
                                {
                                        q2=q1;
                                        q1=q1->next;
                                }
                                else if(num1==q1->num)
                                {
                                        q2->next=q1->next;
                                        q1->next=NULL;
                                        break;
                                }
                        }
                }
        }
        print(q);
}

jackz007 发表于 2021-1-21 12:32:33

       你还是先把前面的求助帖结了吧。

MeowMoo 发表于 2021-1-21 13:04:19

jackz007 发表于 2021-1-21 12:32
你还是先把前面的求助帖结了吧。

哈哈哈,好了,搞忘了

jackz007 发表于 2021-1-21 14:08:50

      始终把被调用的函数放在调用函数的前面就可以避免对函数的声明。就像下面这样,把 main() 放在最后。
#include <stdio.h>
#include <stdlib.h>

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

int n;

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

struct student *creat()
{
      struct student *p1,*p2,*head;
      n=0;
      head=NULL;
      p2=(struct student *)malloc(sizeof(struct student));
      while(1)
      {
                p1=(struct student *)malloc(sizeof(struct student));
                printf("Please enter this student number:");
                scanf("%d",&p1->num);
                printf("Please enter this student score:");
                scanf("%f",&p1->score);
                if(0==p1->num)
                {
                        break;
                }
                else
                {
                        n++;
                        if(1==n)
                        {
                              head=p1;
                              p2=p1;
                        }
                        else
                        {
                              p2->next=p1;
                              p2=p1;
                        }
                }               
}
      p2->next=NULL;

      return head;
}

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

int main(void)
{
      int m                                  ;
      struct student * stu = NULL            ;
      stu = creat()                        ; // 返回链表头节点
      printf("\nThere are %d record!\n\n",n) ;
      print(stu)                           ; // 输出所有节点
      printf("请输入你想删除的学生的编号:") ;
      scanf("%d" , & m)                      ;
      printf("\n\n")                         ;
      stu = del(stu , m)                     ;
      printf("\n\n")                         ;
}

MeowMoo 发表于 2021-1-21 14:45:02

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

哦,明白了,这里q调用的是头节点,如果用户输入0,head是没有被改变的,依然是NULL,直接用头节点进行条件判断,排除空表。行,谢谢大佬
页: [1]
查看完整版本: 链表问题