鱼C论坛

 找回密码
 立即注册
查看: 2418|回复: 12

[已解决]这是一个单链表的递归问题

[复制链接]
发表于 2020-8-10 22:01:13 | 显示全部楼层 |阅读模式
10鱼币
问:一个带头节点的单链表,要删除所有值为X的节点,并释放空间,X不唯一(用递归实现)

这是我的代码:

void Del_X(LinkList L,int x){
        LNode *p;
        if(L==NULL)
                return;
        if(L->data==x){
                p=L;
                L=L->next;
                free(p);
                Del_X(L,x);
        }
        else{
                Del_X(L->next,x);
        }
}


感觉直接free(p)会断链,实际测试也确实有问题,请问问题在哪呢?能怎么改进?
最佳答案
2020-8-10 22:01:14
还是传参数传错了,要传指向指针的指针。
void Del_X(LinkList * L,int x)
{
        LNode *p;
        if(*L==NULL)
                return;
        if((*L)->data==x)
        {
                p=*L;
                *L=(*L)->next;
                free(p);
                Del_X(L,x);
        }
        else
        {
                Del_X(&((*L)->next),x);
        }
}

最佳答案

查看完整内容

还是传参数传错了,要传指向指针的指针。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-8-10 22:01:14 | 显示全部楼层    本楼为最佳答案   
还是传参数传错了,要传指向指针的指针。
void Del_X(LinkList * L,int x)
{
        LNode *p;
        if(*L==NULL)
                return;
        if((*L)->data==x)
        {
                p=*L;
                *L=(*L)->next;
                free(p);
                Del_X(L,x);
        }
        else
        {
                Del_X(&((*L)->next),x);
        }
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-8-10 22:57:02 | 显示全部楼层
本帖最后由 sunrise085 于 2020-8-10 22:59 编辑

对于有头结点的链表,你需要考虑头结点;
此外删除一个节点的时候,需要把后面的节点连接到前面的节点上,然后才能删除中间的节点。
看下图,L不是头结点的时候也是一样的
搜狗截图20200810225843.png
void Del_X(LinkList L,int x){
    LNode *p;
    if(L->next==NULL)// 有头结点,所以需要判断的是下一个节点
            return;
        
    if(L->next->data==x){//头结点是没有数据的,需要判断的是下一个节点的data,然后删除的也是下一个节点
        p=L->next;
        L->next=L->next->next;//你之前的写法,删除一个节点,并没有把链表连接起来
        free(p);
        Del_X(L->next,x);
    }
    else{
        Del_X(L->next,x);
    }
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-8-10 23:26:37 | 显示全部楼层
楼上说得对
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-8-11 09:17:42 | 显示全部楼层
sunrise085 发表于 2020-8-10 22:57
对于有头结点的链表,你需要考虑头结点;
此外删除一个节点的时候,需要把后面的节点连接到前面的节点上, ...

运行了一下,好像会有问题,且无法输出

大神再试验一下

我真的搞不懂啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-8-11 09:21:19 | 显示全部楼层
sunrise085 发表于 2020-8-10 22:57
对于有头结点的链表,你需要考虑头结点;
此外删除一个节点的时候,需要把后面的节点连接到前面的节点上, ...

static void Print(LinkList L){
        while(L->next!=NULL){
                L=L->next;
                printf("%d\n",L->data);
        }
        return;
}
这是我的输出函数
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-8-11 09:27:17 | 显示全部楼层
另外,为什么要用递归呢?函数参数传递没搞懂哦。用普通循环结构你的写法就没问题
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-8-11 09:28:57 | 显示全部楼层
xieglt 发表于 2020-8-11 09:27
另外,为什么要用递归呢?函数参数传递没搞懂哦。用普通循环结构你的写法就没问题

我知道循环可以,这不是做题嘛
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-8-11 09:30:19 | 显示全部楼层
xieglt 发表于 2020-8-11 09:27
另外,为什么要用递归呢?函数参数传递没搞懂哦。用普通循环结构你的写法就没问题

指针的指针感觉有点不好懂
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-8-11 09:30:29 | 显示全部楼层
jsaac 发表于 2020-8-11 09:28
我知道循环可以,这不是做题嘛

参数传错了,要传递指针的指针!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-8-11 09:33:20 | 显示全部楼层
xieglt 发表于 2020-8-11 09:30
参数传错了,要传递指针的指针!

实测可行
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-8-11 09:55:32 | 显示全部楼层
int main(void)
{
        //定义了一个链表头,这是一个指针变量,它的值指向一个地址
        //编译器会在栈里分配一段内存来存储* Head,假设这段内存起始地址为0x12345
        Lnode * Head = NULL;
       
        //初始化链表,假设Head的值 = 0X54321;
        //那么,0x54321就是它指向的地址
        //而0x12345则是这个指针变量的地址,也就是指针的指针
        Head =InitList();
       
        //调用删除节点函数
        //传递指针的值,函数将在栈里分配一段内存,假设这段内存的起始地址为0x12350
        //编译器将把0x54321复制到0x12350这段内存里并传到函数里去。
        //如果0x54321指向的Data == X ,那么free(0x54321)是没有问题的
        //问题出在L= L->next这一句,L的地址是0X12350,这一句相当于把L->next复制到0x12350;
    //而不是复制到Head的地址0X12345,所以Head的值并没有改变。
        Del_X(Head,X)

    //如果是传递指针的指针就不一样
        //同样函数将在栈里分配一段内存,假设这段内存的起始地址为0x12350
        //编译器则将把0x12345复制到0x12350这段内存里并传到函数里去。
        //*L=(*L)->next,就是把(*L)->next复制到0x12345里头,Head的值才得以改变
        Del_X(&Head,X)



        return 0;
}

很拗口,比较难理解,多学多练,慢慢总会理解的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-8-12 00:56:34 From FishC Mobile | 显示全部楼层
xieglt 发表于 2020-8-11 09:55
int main(void)
{
        //定义了一个链表头,这是一个指针变量,它的值指向一个地址

另外,我想知道直接free而并没有连接删除节点前后的两个链表,为什么不会断链呢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-11 07:44

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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