/* * using Morris order traversal O(1) space, post order traversal of binary tree */ /* * Code Reference: * https://github.com/AnnieKim/ForMyBlog/blob/master/20130615/MorrisPostorderTraversal.cpp * * References: * * Julia's comment: (Sept. 5, 2015) * 1. Try to understand the idea of post order traversal of Morris order, how to come out the idea * when to output the traversal order. * * Use example: * 9 / \ 5 8 / \ \ 1 4 7 / \ / 2 3 6 * * So, the call of printReverse() will show up 5 times, * 1st time, printReverse() two arguments both are node (1), output is 1, * 2nd time, both are node (2), output is 2, * 3rd time, printReverse two arguments From: 5, To: 3, so output is 3, 4, 5 * 4th time, both are node (6), poutput is 6, * 5th time, printReverse() two argument From: 9, To: 7, so output is 7, 8, 9 * The post order traversal of Morris order is 1 2 3 4 5 6 7 8 9 * */ public static void postorderMorrisTraversal(TreeNode root) { TreeNode dump = new TreeNode(1); dump.left = root; TreeNode cur = dump, 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 { printReverse(cur.left, prev); // call print prev.right = null; cur = cur.right; } } } }
// print the reversed tree nodes 'from' -> 'to'. public static void printReverse(TreeNode from, TreeNode to) { reverse(from, to); TreeNode p = to; while (true) { System.Console.WriteLine(" " + p.val + " "); if (p == from) break; p = p.right; } reverse(to, from); }
static void Main(string[] args) { TreeNode root = new TreeNode(9); root.left = new TreeNode(5); root.left.left = new TreeNode(1); root.left.right = new TreeNode(4); root.left.right.left = new TreeNode(2); root.left.right.right = new TreeNode(3); root.right = new TreeNode(8); root.right.right = new TreeNode(7); root.right.right.left = new TreeNode(6); /* 9 / \ 5 8 / \ \ 1 4 7 / \ / 2 3 6 */ postorderMorrisTraversal(root); System.Console.WriteLine(" "); postorderMorrisTraversal(root); // check to see if the tree structure remains the same }
// reverse the tree nodes 'from' -> 'to'. /* * 9 / \ 5 8 / \ \ 1 4 7 / \ / 2 3 6 * From: node (5) -> node (3) * (5).right.val = 4 * (5).right.right.val = 3 * * Reverse: * (3).right.val = 4 * (4).right.val = 5 * * Reverse techniques: * n1 * \ * n2 * \ * n3 * 1. save n2.right first, n3 = n2.right, * 2. set n2.right to n1 * 3. moves to next iteration: * n1 = n2; * n2 = n3; * also check the condition if n1 is the end of the nodes. * */ public static void reverse(TreeNode from, TreeNode to) { if (from == to) return; TreeNode n1 = from, // node 1 n2 = from.right, // node 2, node 2 is the right child of node 1, need to reverse the link. n3; // temporary storage while (true) { n3 = n2.right; // before reverse, save the third node n2.right = n1; // reverse n1 = n2; n2 = n3; if (n1 == to) break; } }