关于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:
fNext->fPrevious = &C→ 等价于B.fPrevious = &C,让B的前驱变成CfNext = &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
相关产品推荐
相关产品推荐

