递归删除链表节点(为什么不断链解析)

void del_list(LinkList *&L, ElemType x) {
    LNode *p = (LNode *)malloc(sizeof(LNode));
    if (L == NULL) {
        return;
    }
    if (L->data == x) {
        p = L;
        L = L->next;  //不用访问前驱节点,怎么做到不断链的删除节点
        free(p);
        del_list(L, x);
    }
    else {
        del_list(L->next, x);
    }
}

上述代码的功能是递归的删除以L为首节点指针的单链表中所有值等于x的节点。在百度检索之后,看了一下他们的解析,并不能解答我心中的疑惑,在这里记录一下我的看法。
首先理解一下递归,递归和循环不同的是,递归是栈中操作,每一次的递归相当于一次压栈操作,直到到达递归出口。
例如:一个三个节点的单链表 1->2->3,L指向首节点。
执行 del_list(L,2);
程序栈:

程序栈

如上图所示,每次经过一次递归,就会进行一次压栈操作,直到递归出口。众所周知,栈是先进后出,所以上述栈在执行的时候会是如下顺序:

由于这个方法是删除值为2的节点,对于不是2节点没有操作,所以主要看第二个操作。

del_list(L->next,2);

 if (L->data == x) {
        p = L;
        L = L->next;  //注意将方法参数带入后,原本的语句就会变成L->next = L->next->next
        free(p);
        del_list(L, x);
    }

可以看到,将方法参数 ‘L->next’ 带入,原本会断链的语句现在变成了L->next = L->next->next,明显是正确的,成功删除了值为2的节点且没有断链。


今天回看自己写的博客的时候,虽然递归的执行流程是解释清楚了,但是还是解释递归删除节点不断链的时候还是有些解释不通。
实践是检验真理的唯一途径,我写了上述方法的测试,测试发现编译都成问题,问题出在下面这段代码。

void del_list(LinkList *&L, ElemType x) {

可以注意到方法型参中有 ‘&’ 符号,在之前学习ANSI C中都没有这种用法,表示很疑惑。终究还是见识少了,我搜索之后发现是c++ 中对于引用的申明。
这样就可以说的通了,

 del_list(L->next,2);

在上述代码执行的时候,由于方法第一个形参声明的是对于指向LinkList结构体地址的引用,所以在执行

  L = L->next; // &L = head->next

在对于引用类型的数据赋值的时候,赋值的是引用的数据的值,即"head->next = L->next;",完成了前驱指针的更新。

	int b = 1;
	int &a = b;
	a = 2;
	printf("%d",b);

上述代码输出的无疑会是2。

  • 19
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

来日可期1314

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值