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

关于DoublyLinkedNode类append方法代码的疑问咨询

双向链表append方法代码解析

我来帮你拆解这段双向链表的append代码,搞清楚这几个操作的核心逻辑:

先贴出完整的append方法代码方便参考:

void DoublyLinkedNode<DataType>::append(Node& aNode) { 
    aNode.fPrevious = this; 
    if (fNext != &NIL) { 
        aNode.fNext = fNext; 
        fNext->fPrevious = &aNode; 
    } 
    fNext = &aNode; 
}

结合构造函数的初始化逻辑:每个新节点创建时,fPrevious和fNext都会指向NIL(这是一个哨兵节点,用来标记链表的头尾边界)。


问题1:fNext->fPrevious = &aNode 和 fNext = &aNode 为什么操作的不是同一个值?

这两个操作完全是在修改不同对象的成员变量,本质是两回事:

  • fNext是当前调用append方法的节点的成员,它存储的是当前节点的下一个节点的地址。进入if分支时,fNext指向的是原来的后继节点(我们暂且叫它oldNext)。
  • fNext->fPrevious = &aNode:这里的fNext->fPrevious其实是oldNext的fPrevious成员,我们把它改成新节点aNode的地址——这一步是让原来的后继节点,把它的前驱指针指向新节点,让oldNext和aNode建立双向关联。
  • fNext = &aNode:这一步是修改当前节点自己的fNext成员,让当前节点的后继指针直接指向新节点aNode,完成当前节点到新节点的关联。

举个直观的例子:假设当前节点是A,原来的后继是B,现在要插入新节点C:

  1. fNext->fPrevious = &C → 等价于B.fPrevious = &C,让B的前驱变成C
  2. fNext = &C → 等价于A.fNext = &C,让A的后继变成C
    最终就形成了A ↔ C ↔ B的双向链表结构。

问题2:aNode.fPrevious = this 的具体含义

this在C++成员函数里,代表调用这个函数的对象的地址。在这里,调用append的是某个DoublyLinkedNode实例(比如上面例子里的A),所以this就是&A。

aNode.fPrevious = this 就是把新节点aNode的前驱指针,指向当前调用append的节点——这一步是先给新节点的前驱“定位”,让它和当前节点先建立单向关联,后面再处理它和原来后继节点的关联(如果存在的话)。

还是用上面的例子,这一步就是C.fPrevious = &A,先让C明确自己的前一个节点是A。


最后补充下哨兵节点NIL的作用:当当前节点是链表的尾节点时,fNext指向NIL,此时if分支不会执行,新节点的fNext会保持初始化的NIL,然后当前节点的fNext指向新节点,新节点就变成了链表的新尾节点,完美完成尾节点的追加操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:27:55