为什么删除结点要返回元素e的值呢

**单链表的结点删除并返回删除的值C语言数据结构
每一句基本上都有注释,如还有哪些细节不懂,欢迎下方评论

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

#define NULL 0
//创建单链表结构体 
typedef struct LNode{ 
    int data;                        //表示结点的数据域 
    struct LNode * next;            //表示结点的指针域 
}LNode,*LinkList;
//声明ADT 
LinkList InitList_L(LinkList &L);
void GreateList_L(LinkList &L,int n);
LinkList ListDelete_L(LinkList &L,int del,int &e);
void Display_L(LinkList &L,int n);
//主函数,对数据的操作都在这里 
int main(){
    LinkList L;
    int n,del; 
    int * e;
    //对数据进行初始化 
    InitList_L(L);
    printf("请输入链表的长度:");
    scanf("%d",&n);
    //使用头插法创建链表 
    GreateList_L(L,n);
    printf("\n创建的");
    //将创建的链表打印出来 
    Display_L(L,n);
    printf("\n请输入要删除第几个节点:");
    scanf("%d",&del);
    //对链表中的某个结点进行删除 
    L = ListDelete_L(L,del,*e); 
    printf("\n删除结点的值为:%d",*e);
    printf("\n删除后的");
    Display_L(L,n);
    return 0;
    
} 
//链表的初始化,使链表变为只有头结点的链表 
LinkList InitList_L(LinkList &L){
    L=(LinkList)malloc(sizeof(LNode));
    L->next = NULL;
    return L;
}
//创建链表 
void GreateList_L(LinkList &L,int n){
    //这里采用头插法,使用倒序输入 
    LinkList p;
    int i;
    //有的书上这里是对链表L进行头结点的分配内存
    //因为这个代码已经有初始化函数了,这里就不用再给头结点进行操作了
    //此时的链表中已经包含了头结点 
    for(i=n;i>0;--i){
        //为新节点分配内存 
        p = (LinkList)malloc(sizeof(LNode));
        printf("\n请输入链表的值:");
        scanf("%d",&p->data);
        //将头结点的下一个结点的地址赋值给要插入结点的指针域中
        //使得新结点位于链表的最前,头结点的后面 
        p->next = L->next;
        //将新插入的结点地址赋值给头结点的指针域,使得头结点和新结点进行连接 
        L->next = p; 
    }
}
//删除结点,并返回删除结点的数据 
LinkList ListDelete_L(LinkList &L,int del,int &e){
    LinkList p,q;
    p = L;
    //计数 
    int j = 0;
    //进入循环的条件为,链表不为空,且计数器要小于要删除结点的位置 
    while(p->next  && j<del-1){
        //p指针每次循环向后移动一位 
        p = p->next;
        //计数+1 
        j++;
    }
    //如果链表为空或者计数器大于要删除结点的位置,则返回该链表 
    if(!(p->next) || j>del+1){
        return L;
    }
    //使用一个空闲指针,将要删除结点的地址赋值给它 
    q = p->next;
    //再将要删除结点的下一个结点的地址赋值给要删除结点的前一个结点的指针域 
    p->next = q->next;
    //并将要删除结点的数据域赋值给该数据域指针类型,用于返回数据 
    e = q->data;
    //释放空闲指针 
    free(q);
    return L;
} 
//打印单链表 
void Display_L(LinkList &L,int n){
    LinkList p;
    int i;
    //首先将指针指向首元结点 
    p = L->next;
    printf("单链表为:");
    for(i=0;i<n;i++){
        printf("%d ",p->data);
        p = p->next;
        //每打印一个结点,指针向后移动一位 
    }
}

为什么删除结点时要保存或返回元素e的值呢?意义在哪里?我觉得只要delede元素后就已经完成删除了,为什么会出现这一步骤呢?
版权声明:本文为CSDN博主「ylffly21」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_44208167/article/details/123057193

这个删除时是否返回数据看你的设计思路,没有硬性规定必须要返回元素值,你可以返回1表示删除成功,0表示失败甚至不返回值也行。将返回值返回给调用函数,可以更好的了解程序运行状况,避免误删除

  • 以下回答由chatgpt基于相关博客总结生成:

    问题中涉及的是单链表中结点的删除操作,并返回被删除元素的值。下面给出解释和代码实现:

    在单链表中删除结点时,确实只需要删除元素就可以完成删除操作,但有时我们可能需要被删除元素的值。返回被删除元素的值有以下几个原因:

    1. 需要对被删除的元素进行处理或记录:在实际应用中,有时需要对被删除的元素进行特定的处理,例如统计被删除的元素总数、记录被删除元素的日志等。

    2. 方便后续操作:有时删除操作可能是为了后续的其他操作而进行的,返回被删除元素的值可以方便后续操作的进行。

    3. 提供删除的反馈信息:返回被删除元素的值可以向调用者提供删除操作的结果。

    在给出具体代码实现之前,需要先对给出的代码进行修改:

    1. 整理代码:去除多余的空行和无用的变量。
    2. 修改循环链表的实现方式:将原有的循环链表改为普通的单链表结构,以便进行删除结点的操作。

    修改后的代码如下:

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef char ElemType;
    typedef struct Node
    {
        ElemType data;
        struct Node *next;
    } LNode, *LinkList;
    
    void CreatList(LinkList &L, int m)
    {
        int i;
        LinkList p, s;
        L = (LinkList)malloc(sizeof(LNode));
        L->next = NULL;
        p = L;
        if (m != 0)
            printf("请依次输入%d个数据元素:\n", m - 1);
        getchar(); // 处理之前的换行符
    
        for (i = 0; i < m; i++)
        {
            s = (LinkList)malloc(sizeof(LNode));
            scanf("%c", &s->data);
            getchar(); // 处理输入时的回车符
            p->next = s;
            p = p->next;
        }
        p->next = NULL;
    }
    
    void ListPrint(LinkList L)
    {
        LinkList p;
        p = L->next;
        if (!p)
            printf("输出链表失败!\n");
        while (p)
        {
            printf("%c", p->data);
            p = p->next;
        }
        printf("\n");
    }
    
    void ListInsert(LinkList &L, int i, ElemType e)
    {
        LinkList s, p;
        p = L;
        for (int j = 0; p && j < i - 1; j++)
            p = p->next;
        if (!p || j > i - 1)
        {
            printf("i值错误\n");
            return;
        }
        s = (LinkList)malloc(sizeof(LNode));
        s->data = e;
        s->next = p->next;
        p->next = s;
    }
    
    ElemType ListDelete(LinkList &L, int i)
    {
        LinkList p, q;
        ElemType e;
        p = L;
        for (int j = 0; p && j < i - 1; j++)
            p = p->next;
        if (!p || j > i - 1 || !p->next)
        {
            printf("i值错误或删除位置不存在\n");
            return '\0'; // 返回空字符
        }
        q = p->next;
        p->next = q->next;
        e = q->data;
        free(q); // 释放删除的结点内存
        return e;
    }
    
    int main()
    {
        LinkList L;
        int n;
        printf("请输入数据元素个数: ");
        scanf("%d", &n);
        CreatList(L, n + 1);
    
        printf("原始链表: ");
        ListPrint(L);
    
        // 删除第2个结点,并返回被删除的元素的值
        ElemType deletedData = ListDelete(L, 2);
        printf("删除的元素: %c\n", deletedData);
    
        printf("删除后的链表: ");
        ListPrint(L);
    
        return 0;
    }
    

    运行上述代码后,可以看到输出结果中有三部分内容:

    1. 原始链表:输出输入的数据元素。
    2. 删除的元素:输出删除操作返回的被删除元素的值。
    3. 删除后的链表:输出删除操作后的链表结果。

    这样就能够在删除结点的同时返回被删除的元素的值了。