4

The morris traversal works great for InOrder traversal with O(n) time and O(1) space. Is it possible to just by changing a few things achieve PreOrder and PostOrder traversal using the same algorithm.

shreyasva
  • 13,126
  • 25
  • 78
  • 101

6 Answers6

2

I dont think we can Implement post order using threads . In post order we have to traverse both the children then their parent. We can establish a link from child to parent, but after that we cant go up this parent coz their are no links.(one points to left child and one to its right child none pointing upwards)

             1
            / \
           2   3
          / \
         4   5

we can create a thread at 4's right node pointing to node 5 . We can create a thread at 5's right node pointing to node 2 .

But at node 2 there are no empty pointers to create any threads. Node 2 already has its pointers pointing to node 4 & 5.

Community
  • 1
  • 1
Swas_99
  • 2,350
  • 1
  • 15
  • 19
1

I know the solution for Preorder using morison Algo.

here is the java Code

public static void morisonPreOrder(TreeNode root) {
    TreeNode curr = root, tmp=null;

    while (curr != null) {
        if(curr.leftNode == null) {
            System.out.print(curr.value + "  ");
            curr = curr.rightNode;
        } else {
            tmp = curr.leftNode;
            while (tmp.rightNode != null && tmp.rightNode != curr) {
                tmp = tmp.rightNode;
            }

            if(tmp.rightNode == null) {
                System.out.print(curr.value + "  ");
                tmp.rightNode = curr;
                curr = curr.leftNode;
            } else {
                tmp.rightNode = null;
                curr = curr.rightNode;
            }
        }
    }
}
Mario F
  • 45,569
  • 6
  • 37
  • 38
Fire-Hox
  • 523
  • 4
  • 5
1

Post-order can be achieved by simply reversing the in-order Morris algorithm. To explain,

In-order python Morris implementation:

def in_order(root):
    if not root:
        return []
    current = root
    in_order_list = []
    while current:
        if not current.left:
            in_order_list += [current.val] # Mark current as visited
            current = current.right
        else:
            # find the right most of the left tree
            predecessor = current.left
            while (predecessor.right) and (predecessor.right != current):
                predecessor = predecessor.right
            # and create a link from this to current
            if not predecessor.right:
                predecessor.right = current
                current = current.left
            else: # now bring back the tree to it's original shape
                 predecessor.right = None
                 in_order_list += [current.val]
                 current = current.right
    return in_order

For post-order, begin with current and if current.right is empty - start looking towards left. If not, find left most predecessor and link the left of this predecessor back to current. (In short, flip the lefts in in-order to rights and keep inserting nodes to the beginning of the visited list ;) )

Post-order Python Morris

def post_order(root):
    if not root:
        return []
    current = root
    post_order_list = []
    while current:
        if not current.right:
            post_order_list.insert(0, current.val)
            current = current.left
        else:
            # find left most of the right sub-tree
            predecessor = current.right
            while (predecessor.left) and (predecessor.left != current):
                predecessor = predecessor.left
            # and create a link from this to current
            if not predecessor.left:
                post_order_list.insert(0, current.val)
                predecessor.left = current
                current = current.right
            else:
                predecessor.left = None
                current = current.left
    return post_order
coppaste
  • 166
  • 1
  • 3
0

Here is the sample code for pre order traversal using modified morris traversal.

You can use in a similar way to modify the right predecessor's left link for post order traversal.

I didn't get time to test the code. Please let me know if something is wrong in this code.

void preOrderNonRecursive( BSTNode* root )
{
    if(!root)
        return;
    BSTNode* cur = root;

    while(cur)
    {
        bool b = false;
        BSTNode* pre = NULL;
        if (cur->left)
        {
            pre = cur->left;
            while(pre->right && pre->right != cur)
                pre = pre->right;
            if(!pre->right)
            {
                pre->right = cur;
                b = true;
            }               
            else
                pre->right = NULL;
        }   
        else
            printf("%d\n",cur->val);

        if(b)
        {   
            printf("%d\n",cur->val);
            cur = cur->left;        
        }
        else            
            cur = cur->right;
    }
}
Jason Sturges
  • 15,855
  • 14
  • 59
  • 80
0

/PreOrder Implementation Without stack and recursion/

private static void morrisPreorder(){
        while(node != null){
            System.out.println(node.getData());
            if (node.getLeftNode() == null){
                node = node.getRightNode();
            } else {
                Node rightnode = node.getRightNode();
                Node current = node.getLeftNode();
                while(current.getRightNode() != null && current.getRightNode().getData() != node.getData())
                    current = current.getRightNode();
                if(current.getRightNode() == null){
                    current.setRightNode(node.getRightNode());
                    node = node.getLeftNode();
                } else {
                    node = node.getRightNode();
                }
            }
        }
    }
nchouhan
  • 101
  • 1
  • 1
0

The preorder traversal has been answered above.

For the postorder traversal, the answer is "Yes" as well.

The only modifications you need are: 1. When the right child of the predecessor is current node, set the right child to null and reversely output all the nodes from the left child of the current node to the predecessor. 2. Set up a dummy node and set its left child to the root of the tree.

The Java code is written here:

    private void printPostTraverse(List<Integer> traverseList, TreeNode start, TreeNode end) {
        TreeNode node = start;
        int insertIndex = traverseList.size();
        while (node != end) {
            traverseList.add(insertIndex, node.val);
            node = node.right;
        }
        traverseList.add(insertIndex, node.val);
    }

    public List<Integer> postorderMorrisTraversal(TreeNode root) {
        List<Integer> traverseList = new ArrayList<>();
        TreeNode dummy = new TreeNode(-1);
        dummy.left = root;
        TreeNode cur = dummy, prev = null;
        while (cur != null) {
            if (cur.left == null) {
                cur = cur.right;
            } else {
                prev = cur.left;
                while (prev.right != null && prev.right != cur)
                    prev = prev.right;

                if (prev.right == null) {
                    prev.right = cur;
                    cur = cur.left;
                } else {
                    // Modification on get the traversal list
                    printPostTraverse(traverseList, cur.left, prev);
                    prev.right = null;
                    cur = cur.right;
                }
            }
        }
        return traverseList;
    }
William Chou
  • 157
  • 2
  • 8