📜  使用 Morris Traversal 对二叉树进行层序遍历

📅  最后修改于: 2021-09-07 05:12:58             🧑  作者: Mango

给定一棵二叉树,任务是以层序方式遍历二叉树。

例子:

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

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

做法:思路是使用Morris Preorder Traversal,在层序遍历中遍历树。

观察:使用Morris preorder traversal对树的遍历主要有两个观察。那是 –

  • 在 Preorder 遍历中,首先访问级别的最左侧节点,因为它可以用于以级别顺序方式遍历树。
  • 由于我们在二叉树的顶视图中保持节点的水平距离,同样如果我们保持当前节点的级别并根据移动相应地增加或减少级别,则可以轻松遍历节点。

与 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)

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live