鱼C论坛

 找回密码
 立即注册
查看: 1369|回复: 2

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

[复制链接]
发表于 2022-7-17 13:57:30 | 显示全部楼层 |阅读模式

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

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

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



#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;
}
最佳答案
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 ,删除函数的返回值类型错误,以及内存泄漏:您申请的空间完全没有释放,尽管在该程序中实际不会造成影响,但这是错误的、不应该的,等问题。链表建立的过程稍显繁琐而且会进行一次不必要的分配,这并不是错误(但是这次不必要的分配也没有释放,仍然是问题),也可能还有改进的空间。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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 ,删除函数的返回值类型错误,以及内存泄漏:您申请的空间完全没有释放,尽管在该程序中实际不会造成影响,但这是错误的、不应该的,等问题。链表建立的过程稍显繁琐而且会进行一次不必要的分配,这并不是错误(但是这次不必要的分配也没有释放,仍然是问题),也可能还有改进的空间。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

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

谢谢大佬
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-22 16:18

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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