📜  使用Morris遍历遍历二叉树的级序。

📅  最后修改于: 2021-05-04 22:57:50             🧑  作者: Mango

给定一个二叉树,任务是以级别顺序方式遍历二叉树。

例子:

Input: 
         1
        / \
       2   3
Output:
1
2 3

Input:
         5
        / \
       2   3
        \
         6
Output:
5
2 3
6

方法:这个想法是使用Morris Preorder Traversal来以级别顺序遍历遍历树。

观察结果:使用Morris顺序遍历,对树的遍历主要有两个观察结果。那是 –

  • 在“预遍历遍历”中,首先访问某个级别的最左节点,因此可以使用它以级别顺序的方式遍历树。
  • 当我们在二叉树的顶视图中保持节点的水平距离时,类似地,如果我们保持当前节点的水平并根据移动相应地增加或减少水平,则可以轻松地遍历这些节点。

就像在莫里斯(Morris)预遍历中一样,我们将左子节点的最右节点与其有序后继节点相连,以保持运动,以便在完全探查父节点的左子节点之后可以回溯到父节点的右子节点。因此,当移到左侧孩子的最右侧孩子时,我们可以跟踪级别中增量的数量,以计算该孩子的级别顺序继承者。

以下是借助示例对方法的说明:

下面是上述方法的实现:

Python
# Python implementation of the Level 
# order traversal using Morris traversal
  
# Class of the node of the 
# Binary Tree
class Node:
    def __init__(self, data):
        self.data = data 
        self.left = None
        self.right = None
  
# Function to traverse the Binary
# tree in the Level Order Fashion
def levelOrderTraversal(root):
      
    # Current Node is marked as
    # the Root Node
    curr = root
    level = 0
  
    # Loop to traverse the Binary
    # Tree until the current node 
    # is not Null
    while curr:
  
        # If left child is null, print the 
        # current node data. And, update  
        # the current pointer to right child. 
        if curr.left is None:
  
            # Return the current node with
            # its level
            yield [curr, level] 
            curr = curr.right
            if curr:
                level += 1
            else:
                level -= 1
        else:
  
            # Find the inorder predecessor 
            prev = curr.left 
            to_up = 0
  
            # Loop to find the right most 
            # node of the left child of the
            # current node
            while prev.right is not None and \
                    prev.right is not curr: 
                prev = prev.right
                to_up += 1
  
            # If the right child of inorder 
            # predecessor already points to 
            # the current node, update the  
            # current with it's right child 
            if prev.right is curr:
                prev.right = None
                curr = curr.right 
                level -= to_up + 1
              
            # else If right child doesn't
            # point to the current node, 
            # then print this node's data 
            # and update the right child
            # pointer with the current node  
            # and update the current with
            # it's left child 
            else:
                yield [curr, level]
                prev.right = curr  
                curr = curr.left
                level += 1
  
# Driver Code
if __name__ == "__main__":
    root = Node(5)
    root.left = Node(2)
    root.right = Node(3)
    root.left.right = Node(6)
  
    # Output List to store the 
    # Level Order Traversed Nodes
    outputData = [[] for i in range(100)]
  
    for node, level in levelOrderTraversal(root):
        outputData[level].append(node.data)
  
    h = 0
  
    # Loop to find the height of the 
    # Binary Tree
    for i in outputData:
        if i:
            h += 1
        else:
            break
  
    # Loop to print the Data
    for i in range(h):
        print(' '.join(map(str, outputData[i])))


输出:
5
2 3
6

性能分析:

  • 时间复杂度:与上述方法一样,每个节点最大触摸两次,因此时间复杂度为O(N) ,其中N是节点数。
  • 辅助空间:与上述方法一样,由于使用的辅助空间为O(1) ,因此没有使用额外的空间。