You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++单链表中指针与指向指针的指针的困惑:删除偶数节点解析

单链表偶数节点删除:两段代码的核心差异解析

先看两段实现删除单链表偶数节点的代码:

第一段代码(存在断链问题)

void delete_even()
{
    node* ptr = head;
    while (ptr)
    {
        if (ptr->data % 2 == 0)
        {
            node* aux = ptr;
            ptr = ptr->next;
            delete aux;
        }
        else
        {
            ptr = ptr->next;
        }
    }
}

这段代码的问题很明确:它只在自己的遍历指针ptr上移动,却没有修改链表本身的链接关系。举个具体例子:

  • 若链表是1 -> 2 -> 3,删除2时,ptr先指向2,再跳到3,接着删除2,但节点1的next指针仍指向已被释放的2,后续访问链表会出现野指针或断链。
  • 若头节点本身是偶数(比如2 -> 3 -> 4),删除头节点后,全局head指针完全没被更新,依然指向已释放的节点,整个链表直接“失联”。

第二段代码(正确实现)

void delete_even()
{
    node **p= &head;
    while (*p)
    {
        if ((*p)->data % 2 == 0)
        {
           node *nextptr=*p;
           *p=(*p)->next;
           delete nextptr;
        }
        else
        {
            p= &(*p)->next;
        }
    }
}

这段代码用了指向指针的指针p,本质是直接操作链表中存储节点地址的“关键位置”:

  • 初始时p指向全局head指针的地址,*p就是head本身。
  • 当要删除节点时,*p = (*p)->next直接修改了这个关键位置的值:如果是头节点,相当于更新head指针,让它跳过被删除的节点;如果是中间节点,p此时指向的是前一个节点的next成员的地址,修改*p就是让前一个节点的next直接指向被删除节点的下一个节点,完美维护了链表的链接。
  • 如果不需要删除,就把p移动到当前节点的next成员的地址,继续遍历。

核心差异

两段代码的本质区别在于是否能修改链表的指针引用:

  • 第一段代码的ptr是普通指针,它仅存储节点的地址,但修改ptr不会影响链表本身的指针(比如head或其他节点的next),删除节点后,前驱节点的next依然指向已释放的内存,导致断链。
  • 第二段代码的p是指向指针的指针,它直接指向链表中用来记录下一个节点地址的“容器”(要么是head变量,要么是节点的next成员),删除时直接修改这个容器里的地址,让链表的链接关系被正确更新,从根源上避免了断链。

内容的提问来源于stack exchange,提问作者Klau

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 02:45:14