ZBLOG

vector ans; TreeNode* p1 = root; TreeNode* p2 = NULL; while (p1 != NULL) { p2 = p1->left; if (p2 != NULL) { while (p2->right != NULL && p2->right != p1) ...

这段代码实现的是一种遍历二叉树的方法,具体来说,它是前序遍历的 Morris 遍历算法。Morris 遍历是一种不使用栈或递归,且只使用常数空间复杂度的树遍历方法。下面对代码进行详细解释,并举例说明其运行步骤。

代码解释

  1. 初始化

    • 创建一个 vector<int> ans 用于存储遍历结果。
    • 使用两个指针 p1p2p1 初始指向树的根节点,p2 初始化为 NULL。
  2. 主循环

    • p1 不为 NULL 时,执行以下操作:
  3. 寻找右子树最右侧节点

    • p2 设置为 p1->left(当前节点的左子树)。
    • 如果左子树存在(即 p2 != NULL),进入内部循环以找到左子树最右侧的节点(即最深的右叶子节点):
      
      while (p2->right != NULL && p2->right != p1)
      
    • 一旦找到这个最右侧节点,将其的右指针指向当前节点 p1,并将当前节点值加入到答案中,然后将当前指针移动到左孩子继续处理。
    • 如果找到的是回到父亲节点的情况(即 p2->right == p1),则将 p2->right = NULL 断开这种连接。
  4. 如果没有左孩子

    • 直接将当前节点值添加到结果列表中,然后移动到右子树。
  5. 返回结果

    • 最终返回填充好的结果数组 ans.

举例说明

假设有如下二叉树:

        1
       / \
      2   3
     / \
    4   5

步骤:

  • 初始状态

    • 当前指针:p1 = 1
  • 第一轮迭代 (p1 = 1):

    • 左孩子是 2, 找到它的最右侧是 5.
    • 将从 5.right = null -> p1.
    • 将输出 1.
    • 移动到左儿子: p1 = 2
  • 第二轮迭代 (p1 = 2):

    • 左孩子是 4, 它没有右边,所以输出 [1, 2].
    • 移动: 到它的儿子: -> p1=4.
  • 第三轮迭代 (p1 = 4):

    • 没有左边,所以直接输出 [0,0,0] 为 [3,4].
  • … (继续按照相同逻辑)

最终运行完毕后,这个程序会返回一个包含 [4, 2,5 ,3 ,0 ].

这个过程保证了每个结点都被访问并通过更新边而不是通过 stack或者 recursion 保持空间复杂度。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=20511

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?