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

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);
程序栈:
del_list(L->next->next,2);
del_list(L->next,2);
del_list(L,2);


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

  1. del_list(L->next->next,2);
  2. del_list(L->next,2);
  3. 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->next,明显是正确的,成功删除了值为2的节点且没有断链。

你可能感兴趣的:(分享经验,c语言,递归,单链表,删除节点)