Explain Morris inorder tree traversal without using stacks or recursion

前端 未结 8 1083
别跟我提以往
别跟我提以往 2020-11-27 09:15

Can someone please help me understand the following Morris inorder tree traversal algorithm without using stacks or recursion ? I was trying to understand how it works, but

相关标签:
8条回答
  • If I am reading the algorithm right, this should be an example of how it works:

         X
       /   \
      Y     Z
     / \   / \
    A   B C   D
    

    First, X is the root, so it is initialized as current. X has a left child, so X is made the rightmost right child of X's left subtree -- the immediate predecessor to X in an inorder traversal. So X is made the right child of B, then current is set to Y. The tree now looks like this:

        Y
       / \
      A   B
           \
            X
           / \
         (Y)  Z
             / \
            C   D
    

    (Y) above refers to Y and all of its children, which are omitted for recursion issues. The important part is listed anyway. Now that the tree has a link back to X, the traversal continues...

     A
      \
       Y
      / \
    (A)  B
          \
           X
          / \
        (Y)  Z
            / \
           C   D
    

    Then A is outputted, because it has no left child, and current is returned to Y, which was made A's right child in the previous iteration. On the next iteration, Y has both children. However, the dual-condition of the loop makes it stop when it reaches itself, which is an indication that it's left subtree has already been traversed. So, it prints itself, and continues with its right subtree, which is B.

    B prints itself, and then current becomes X, which goes through the same checking process as Y did, also realizing that its left subtree has been traversed, continuing with the Z. The rest of the tree follows the same pattern.

    No recursion is necessary, because instead of relying on backtracking through a stack, a link back to the root of the (sub)tree is moved to the point at which it would be accessed in a recursive inorder tree traversal algorithm anyway -- after its left subtree has finished.

    0 讨论(0)
  • 2020-11-27 09:38

    I've made an animation for the algorithm here: https://docs.google.com/presentation/d/11GWAeUN0ckP7yjHrQkIB0WT9ZUhDBSa-WR0VsPU38fg/edit?usp=sharing

    This should hopefully help to understand. The blue circle is the cursor and each slide is an iteration of the outer while loop.

    Here's code for morris traversal (I copied and modified it from geeks for geeks):

    def MorrisTraversal(root):
        # Set cursor to root of binary tree
        cursor = root
        while cursor is not None:
            if cursor.left is None:
                print(cursor.value)
                cursor = cursor.right
            else:
                # Find the inorder predecessor of cursor
                pre = cursor.left
                while True:
                    if pre.right is None:
                        pre.right = cursor
                        cursor = cursor.left
                        break
                    if pre.right is cursor:
                        pre.right = None
                        cursor = cursor.right
                        break
                    pre = pre.right
    #And now for some tests. Try "pip3 install binarytree" to get the needed package which will visually display random binary trees
    import binarytree as b
    for _ in range(10):
        print()
        print("Example #",_)
        tree=b.tree()
        print(tree)
        MorrisTraversal(tree)
    
    0 讨论(0)
提交回复
热议问题