当前位置: 首页 > 知识库问答 >
问题:

Morris遍历-如何检查是否达到叶节点?

储承
2023-03-14

在二叉树的morris遍历中,它使用每个右叶节点建立指向当前节点的连接。

假设我们以预先排序的方式遍历树,当到达叶节点时,我们如何判断是否遇到叶节点?

我们不能使用下面的行来检查:if(null==node.left

因为这里node.right指向当前节点,因为莫里斯算法。

一个好方法是,我们总是使用TreeNode对象中的一个字段将访问的节点标记为已访问,但是如果我们没有这个字段,在许多情况下会怎么样?

有人知道如何检查你是否到达叶节点吗?谢谢。

你好,杰克

共有3个答案

慕胡媚
2023-03-14

通过标记已访问的节点,可以简单地解决问题。

因此,叶节点可以通过以下方式来证明:if(null==node.left

好吧,又回到我的问题上来了,我们怎么能有这张关于“isLinked”的唱片呢?

我们可以通过设置一个集合来添加所有morris链接节点来轻松解决此问题。

所以它会是:如果((null==node.left

董和泽
2023-03-14

更新:我想出了关于如何使用Morris遍历检测叶节点的更清晰的解释。所有的叶子是:

  1. 只有一片叶子是树上最合适的。要检测它,您需要检查curr left==nilcurr。右==零
  2. 其余所有的叶子都是人工设置链接到其他节点的叶子。仔细想想,这是有道理的:Morris Traversal不能以任何其他方式从叶节点回溯。因此,所有剩余的leaf都是连接到当前节点的前置节点

如果对您来说仍然没有意义,请查看此Morris遍历的可视化,并注意除一个叶外,所有叶都是“连接”节点,一个位于树的最末端:

这很棘手,但有可能,这是Go中的代码,我用大量棘手的边缘情况进行了测试,同时仍然保持O(1):

func getLeafs(node *TreeNode) []int {
    var leafs []int
    var pre *TreeNode // predecessor of the current node
    curr := node

    for curr != nil {
        if curr.Left == nil {
            if curr.Right == nil { // additional check needed
                leafs = append(leafs, curr.Val)
            }
            curr = curr.Right
            continue
        }

        // curr.Right != nil
        pre = curr.Left
        for pre.Right != nil && pre.Right != curr {
            pre = pre.Right
        }

        if pre.Right == nil {
            pre.Right = curr
            curr = curr.Left
            continue
        }

        // pre.Right == curr
        pre.Right = nil
        if pre.Left == nil { // tricky part! we are not using curr here
            leafs = append(leafs, pre.Val)  // we are actually using pre
        }
        curr = curr.Right
    }

    return leafs
}

基本上,您需要在两个地方进行检查:

  1. 与标准的Morris遍历一样,检查curr。左==nil,然后curr。右==nil
  2. 棘手的部分:不是使用curr,而是需要使用节点,当它们具有到curr节点的链接时。
曾华翰
2023-03-14

就像Jack回答的那样,检查(null==node.left

在这里分享我的代码

def getLeaf(self, root):
    curr = root
    while curr != None:
        if not curr.left and (not curr.right or hasattr(curr, 'isLinked')):
            print("I am a leaf ", curr.val)
        if curr.left is None:
            curr = curr.right
        else:
            prec = curr.left
            while prec.right != None and prec.right != curr:
                prec = prec.right
            if prec.right is None:
                prec.right = curr
                setattr(prec, 'isLinked', True)
                curr = curr.left
            else:
                curr = curr.right
 类似资料:
  • 我需要检查节点是否是二叉树中的叶子。这是我当前的代码。 它向我发送了一条错误消息:“HW371937.hs:C:\Users\lenovo\Desktop\���\��� HASKELL\hw371937。hs:(22,1)-(25,91):函数isLeaf中的非穷举模式” 我不知道如何递归地检查下一个节点是否是叶子。任何帮助都将受到感谢。

  • 在具有父子指针的通用树结构中,是否可以在不遍历完整树的情况下遍历叶节点?例如,从最左边的叶节点开始。想法是在深树上进行优化。

  • 这是一个相当简单的问题,我注意到当我表示一棵树时,无论我用哪种方式(后排序,按顺序,前排序)树叶总是以相同的顺序出现,从左到右。 我只是想知道为什么,这是有原因的吗? 我刚开始研究它们,就想到了这个。 编辑: 我有一棵这样的树: 叶节点为:D、E和F 预购顺序为:A、B、D、C、E、F 顺序是:D,B,A,E,C,F 后序是:D,B,E,F,C,A 叶子节点总是从左到右出现,不管我选择哪个顺序,问

  • 问题内容: 我想知道如何从本质上将下面的目标c代码转换为快速代码。 这将遍历我所需视图上的所有子视图,检查它们是否为文本字段,然后检查是否为空。 到目前为止,这里是我快速翻译的地方: 任何帮助将是巨大的! 问题答案: Swift 5和Swift 4:-一个非常简单的答案,您可以轻松理解:-您可以处理各种对象,例如UILable,UITextfields,UIButtons,UIView,UIIma

  • 问题内容: 假设我有以下字符串: 我想查找的所有匹配项,并确保整个字符串与模式匹配。 所以我做了以下事情: 确保整个模式与我想要的匹配。 遍历模式 有没有办法用一个正则表达式来做到这一点? 问题答案: 您可以通过以下方式验证和迭代一个正则表达式的匹配: 通过在正则表达式的开头放置a来确保匹配之间没有不匹配的字符(例如),这意味着“上一个匹配的结束”。 通过将字符串的长度与进行比较,以检查是否在最后

  • 问题内容: 我有一个Map如下所示的bean: 这ftqSet适合以下数据结构: 在我的测试JSP文件中,我一直在尝试使用来访问数据 : 但是它没有输出${f.feedId}。为什么会这样呢?我将如何访问该结构的各个元素,以便创建一个漂亮的表? 问题答案: 的每次迭代中给出了一个实例,它反过来又和getValue()方法。这与在普通Java中进行操作类似。 例如 在的情况下, 的回报, ,所以你需