1602657656 发表于 2022-7-17 13:57:30

大佬们,能不能帮我看看这个链路的程序除了什么问题

这个链路不能删除第一个结点,其他后面的结点可以删除。有无大佬帮我瞧瞧,呜呜呜,自己琢磨了半天。非常感谢



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

#define len sizeof(struct student)

struct student
{
      int num;
      float score;
      struct student *next;
};

void print(struct student *head);                        //打印链表
struct student *create();                              //创建链表
int delate(struct student *head);

int n = 0;
      
void main()
{
      struct student *p;
      p = create();

      delate(p);

      print(p);

      system("pause");

}

struct student *create()
{

      struct student *p1, *p2, *head;
      p1 = p2 = (struct student *)malloc(len);


      printf("请输入学号:");
      scanf("%d", &p1->num);

      printf("请输入分数:");
      scanf("%f", &p1->score);

      head = NULL;
      n = 0;

      while (p1->num)
      {
                n++;

                if (1 == n)
                {
                        head = p1;
                }
                else if (1 != n)
                {
                        p2->next = p1;

                }

                p2 = p1;
                p1 = (struct student *)malloc(len);

                printf("请输入学号:");
                scanf("%d", &p1->num);

                printf("请输入分数:");
                scanf("%f", &p1->score);
      }
      p2->next = NULL;
      return head;

}


void print(struct student *head)
{
      while(head)
      {
                printf("学号为 %d 的同学分数是:%.2f\n", head->num, head->score);
                head = head->next;
      }
}

int delate(struct student *head)
{
      int i;
      struct student *p1, *p2;
      p1 = p2 = head;

      printf("请输入删除学生的学号:");
      scanf("%d", &i);

      while (p2->next)
      {

                if (i == head->num)
                {
                        head = p1->next;
                        break;
                }
                else if(i == p1->num)
                {
                        p2->next = p1->next;
                        break;
                }
                p2 = p1;
                p1 = p1->next;
      }
      return head;
}

dolly_yos2 发表于 2022-7-17 16:50:27

首先核心问题,为什么第一个元素无法被删除。查看您的删除逻辑,可以看到对于第一个节点就是要删除的节点的情况是特殊处理的,即和其他情况删除的方式不同。这里其实可以注意,当您确定问题“只在删除第一个节点时出现”,而您的实现中又“特殊处理了删除第一个节点的情况”,那就应该格外关注这一部分。在删除函数中,删除第一个节点的操作通过修改 head 指针的指向完成,然而应该注意,这一修改并未应用到后续被使用的 head 指针:指针是按值传递进入函数的,而函数返回的结果并未被使用。因此这一修改只在此函数中生效,当在此函数中完成删除之后从 head 开始遍历将得到正确的结果,但是返回主函数后并无效果。可以考虑的修改:使用返回值,如调用函数时使用p = delate(p);或者改为按引用传递指针,即修改为// 声明
int delate(struct student **head);

// 主函数中
delate(&p);

// 重写此函数
int delate(struct student **head){    // 这里有改动
    int i;
    struct student *p1, *p2;
    p1 = p2 = *head;    // 这里有改动
    printf("请输入删除学生的学号:");
    scanf("%d", &i);
    while (p2->next){
      if (i == (*head)->num){    // 这里有改动
            *head = p1->next;    // 这里有改动
            break;
      }else if(i == p1->num){
            p2->next = p1->next;
            break;
      }
      p2 = p1;
      p1 = p1->next;
    }
    return head;
}
另外,建议您注意错误的拼写(应为 delete 而不是 delate ),主函数必须返回 int ,删除函数的返回值类型错误,以及内存泄漏:您申请的空间完全没有释放,尽管在该程序中实际不会造成影响,但这是错误的、不应该的,等问题。链表建立的过程稍显繁琐而且会进行一次不必要的分配,这并不是错误(但是这次不必要的分配也没有释放,仍然是问题),也可能还有改进的空间。

1602657656 发表于 2022-7-18 15:04:16

dolly_yos2 发表于 2022-7-17 16:50
首先核心问题,为什么第一个元素无法被删除。查看您的删除逻辑,可以看到对于第一个节点就是要删除的节点的 ...

谢谢大佬
页: [1]
查看完整版本: 大佬们,能不能帮我看看这个链路的程序除了什么问题