huafeng 发表于 2023-12-12 22:36:58

单链表

不懂哪里错了,能运行但运行不完
#include<stdio.h>
#include<stdlib.h>
struct student
{
    int num;
    char name;
    char sex;
    int age;
    struct student *next;
};
struct student *input(void)
{
    struct student *head,*p1,*p2;
    p1=(struct student*)malloc(sizeof(struct student));
    scanf("%d%s%s%d",p1->num,p1->name,p1->sex,p1->age);
    p2=p1;
    head=p1;
    while(p1->num!='0')
    {   
      p1=(struct student*)malloc(sizeof(struct student));
      p2->next=p1;
      scanf("%d%s%s%d",p1->num,p1->name,p1->sex,p1->age);
    }
    return(head);
}
void delete(struct student *head)
{
    int a;
    struct student *p;
    p=head;
    printf("请输入要删除的年龄:");
    scanf("%d",&a);
    while(p!=NULL)
    {
      if(p->age==a)
      {
            while(p->next!=NULL)
            {p=p->next;}
      }
      if(p->next==NULL&&p==a)
      {
            p=NULL;
      }
    }
}
int main()
{
    struct student *head;
    printf("请输入学生信息(num为0时即为结束):num: name: sex: age: \n");
    head=input();
    delete(head);
    return 0;
}

FishC 发表于 2023-12-12 22:37:49

这段代码存在一些错误和逻辑问题。我们来逐个修正。

首先,在头文件的引用上有问题,需要包含`<stdio.h>`和`<stdlib.h>`头文件。

然后,在结构体中,`name`应该是一个字符数组,而不是单个字符。即改为`char name`。同样,`sex`也应该是一个字符数组。

接下来,在输入函数`input()`中,几个地方需要进行修改。首先,在使用`scanf`函数读取字符数组时,需要使用`%s`格式,并且在数组名前面加上`&`符号,表示取数组的地址。例如,`scanf("%s", &p1->name)`。然后,在读取`p1->num`的值之后,需要判断`num`是否等于0,如果是,则跳出循环。此外,在分配`p1`的内存之前,应该还原`p2->next`的值,即将其设置为NULL。最后,记得在循环结束后将`p1`的`next`指针指向NULL。

接着,在`delete()`函数中,有几个问题需要解决。首先,当找到要删除的节点后,应该将该节点的下一个节点的地址赋给当前节点的`next`指针,以实现删除操作。然后,在删除节点之后,应该将当前节点指向下一个节点。最后,当找到要删除的节点时,不应该直接将`p`设置为NULL来删除节点,而应该将当前节点的`next`指针设置为NULL。

最后,在`delete()`函数中的循环条件需要修改。应该将`p->next`判断条件放在前面,以避免出现野指针的情况。

下面是修正后的代码:

#include <stdio.h>
#include <stdlib.h>

struct student
{
    int num;
    char name;
    char sex;
    int age;
    struct student *next;
};

struct student *input(void)
{
    struct student *head, *p1, *p2;
    p1 = (struct student *)malloc(sizeof(struct student));
    scanf("%d%s%s%d", &p1->num, p1->name, p1->sex, &p1->age);
    p2 = p1;
    head = p1;
    while (p1->num != 0)
    {
      p1->next = NULL;// 将p1的next指针初始化为NULL
      p1 = (struct student *)malloc(sizeof(struct student));
      scanf("%d%s%s%d", &p1->num, p1->name, p1->sex, &p1->age);
      if (p1->num == 0)// 判断num是否等于0,如果是,则跳出循环
            break;
      p2->next = p1;// 这里需要将p2的next指针指向p1
      p2 = p1;// 并将p2指向p1,以便下一次循环使用
    }
    return(head);
}

void delete(struct student *head)
{
    int a;
    struct student *p = head;
    struct student *pre = NULL;// pre指针用于记录当前节点的前一个节点
    printf("请输入要删除的年龄:");
    scanf("%d", &a);
    while (p != NULL)
    {
      if (p->age == a)
      {
            if (pre == NULL)// 如果pre为NULL,则表明要删除的是头节点
            {
                head = p->next;
                free(p);
                p = head;
            }
            else
            {
                pre->next = p->next;// 将pre的next指针指向p的下一个节点
                free(p);
                p = pre->next;
            }
      }
      else
      {
            pre = p;// 记录当前节点为pre
            p = p->next;// 指向下一个节点
      }
    }
}

int main()
{
    struct student *head;
    printf("请输入学生信息(num为0时即为结束):num: name: sex: age: \n");
    head = input();
    delete(head);
    return 0;
}

请注意,此处只是对原代码的修改和修正,并不能保证完全符合逻辑需求。如果有其他问题,请随时追问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: 单链表