Esempio n. 1
0
        public static void Test()
        {
            /*  binary tree
             *     10
             *    /  \
             *   8   12
             *  /\   /\
             * 7  9 11 13
             */
            TreeNode tree1 = new TreeNode(10, new TreeNode(8, new TreeNode(7, null, null),
                new TreeNode(9, null, null)), new TreeNode(12, new TreeNode(11, null, null), new TreeNode(13, null, null)));

            /*  not binary tree
             *     10
             *    /  \
             *   8   12
             *  /\   /\
             * 7  6 11 13
             */
            TreeNode tree2 = new TreeNode(10, new TreeNode(8, new TreeNode(7, null, null),
             new TreeNode(6, null, null)), new TreeNode(12, new TreeNode(11, null, null), new TreeNode(13, null, null)));

            Debug.Assert(IsBST_Iterative(tree1));
            Debug.Assert(!IsBST_Iterative(tree2));
            Debug.Assert(IsBST_Recursive(tree1));
            Debug.Assert(!IsBST_Recursive(tree2));
        }
Esempio n. 2
0
 // iterative inorder traverse the tree, the array of traversal should be sorted if is BST
 // optimized for space
 // O(N) time, O(1) space
 public static bool IsBST_Iterative(TreeNode root)
 {
     if (root == null) return false;
     Stack<TreeNode> stack = new Stack<TreeNode>();
     TreeNode current = root;
     int tempValue = int.MinValue;
     while (true)
     {
         if (current != null) // not a leaf, search the left subtree
         {
             stack.Push(current);
             current = current.left;
         }
         else
         {
             if (stack.Count == 0) // finished traversal
                 break;
             else
             {
                 current = stack.Pop();
                 if (current.value < tempValue) return false;
                 else tempValue = current.value;
                 current = current.right;
             }
         }
     }
     return true;
 }
Esempio n. 3
0
 private static bool IsBST_Recursive(TreeNode root, int min, int max)
 {
     if (root == null) return true;
     // check the value of node is in range (min, max)
     if (root.value < min || root.value > max) return false;
     // check the left and right child
     return IsBST_Recursive(root.left, min, root.value - 1)
         && IsBST_Recursive(root.right, root.value, max);
 }
Esempio n. 4
0
 // use a queue for current level nodes, another queue for next level nodes
 public static void PrintLevelOrder_by_two_queue(TreeNode root)
 {
     if (root == null) return;
     Queue<TreeNode> currentLevel = new Queue<TreeNode>();
     Queue<TreeNode> nextLevel = new Queue<TreeNode>();
     currentLevel.Enqueue(root);
     int level = 1;
     Console.Write("Level-" + level + ": ");
     while (currentLevel.Count > 0)
     {
         TreeNode node = currentLevel.Dequeue();
         Console.Write(node.value + " ");
         if (node.left != null)
             nextLevel.Enqueue(node.left);
         if (node.right != null)
             nextLevel.Enqueue(node.right);
         if (currentLevel.Count == 0)
         {
             level++;
             if (nextLevel.Count > 0)
                 Console.Write("\nLevel-" + level + ": ");
             else
                 Console.WriteLine();
             currentLevel = nextLevel;
             nextLevel = new Queue<TreeNode>();
         }
     }
 }
Esempio n. 5
0
 // a slightly variant version: use only one queue and a counter
 // to keep track of number of nodes of current level
 public static void PrintLevelOrder_by_one_queue(TreeNode root)
 {
     if (root == null) return;
     Queue<TreeNode> queue = new Queue<TreeNode>();
     queue.Enqueue(root);
     int count = 1;
     int level = 1;
     Console.Write("Level-" + level + ": ");
     while (queue.Count > 0)
     {
         TreeNode node = queue.Dequeue();
         count--;
         Console.Write(node.value + " ");
         if (node.left != null)
             queue.Enqueue(node.left);
         if (node.right != null)
             queue.Enqueue(node.right);
         if (count == 0)
         {
             level++;
             if (queue.Count > 0)
                 Console.Write("\nLevel-" + level + ": ");
             else
                 Console.WriteLine();
             count = queue.Count; // update counter
         }
     }
 }
Esempio n. 6
0
        public static void Test()
        {
            /*
             *        4
             *       / \
             *      2   6
             *     / \ / \
             *    1  3 7  5
             */
            TreeNode node1 = new TreeNode(1);
            TreeNode node3 = new TreeNode(3);
            TreeNode node7 = new TreeNode(7);
            TreeNode node5 = new TreeNode(5);
            TreeNode node2 = new TreeNode(2, node1, node3);
            TreeNode node6 = new TreeNode(6, node7, node5);
            TreeNode node4 = new TreeNode(4, node2, node6);

            TreeNode common1 = LastCommonAncestor(node4, node1, node5);
            Console.WriteLine("LastCommonAncestor is " + common1); // 4
            TreeNode common2 = LastCommonAncestor(node4, node1, node3);
            Console.WriteLine("LastCommonAncestor is " + common2); // 2
            TreeNode common3 = LastCommonAncestor(node4, node1, node6);
            Console.WriteLine("LastCommonAncestor is " + common3); // 4
            TreeNode common4 = LastCommonAncestor(node4, node1, node2);
            Console.WriteLine("LastCommonAncestor is " + common4); // 2
        }
Esempio n. 7
0
 // 1. (low, high) is the index range of the current root,
 //    root.leftChild is (low, dividerIndex) and root.rightChild is (dividerIndex + 1, high)
 // 2. readPointer is the current root pointer in inorder mapping
 public static TreeNode DeserializePreInorder(int[] preorder, int[] inorder,
     int[] mapping, int low, int high, ref int readPointer)
 {
     if (low == high)
     {
         return null;
     }
     TreeNode root = new TreeNode(preorder[readPointer++]);
     int dividerIndex = mapping[root.value];
     root.left = DeserializePreInorder(preorder, inorder, mapping, low, dividerIndex, ref readPointer);
     root.right = DeserializePreInorder(preorder, inorder, mapping, dividerIndex + 1, high, ref readPointer);
     return root;
 }
Esempio n. 8
0
        // inorder iterative traversal without using stacks, Morris Traverse (threaded binary tree)
        // O(N log N) time, O(1) space
        // http://www.geeksforgeeks.org/archives/6358
        /*
            1. Initialize current as root
            2. While current is not NULL
               If current does not have left child
                  a) Make current as right child of the rightmost node in current's left subtree
                  b) Go to this left child, i.e., current = current->left
               Else
                  a) Print current’s data
                  b) Go to the right, i.e., current = current->right
         */
        public static void MorrisTraverse(TreeNode root)
        {
            TreeNode current = root;
            TreeNode prev = null;
            while (current != null)
            {
                if (current.left != null)
                {
                    prev = current.left;
                    while (prev.right != null) // find the prev node, takes O(log N) time
                    {
                        if (prev.right == current) break; // encounter thread, stop
                        prev = prev.right;
                    }

                    if (prev.right == null) // thread is not yet added
                    {
                        prev.right = current; // add thread
                        current = current.left; // search left subtree
                    }
                    else // thread is already there
                    {
                        prev.right = null; // remove thread
                        Console.Write(current.value + " ");
                        current = current.right; // search right subtree
                    }
                }
                else // left subtree is null, search right subtree
                {
                    Console.Write(current.value + " ");
                    current = current.right;
                }
            }
        }
Esempio n. 9
0
 // 1. swap the left subtree and right subtree of the root
 // 2. recursively mirror the left subtree and right subtree
 public static TreeNode MirrorRecursive(TreeNode root)
 {
     if (root == null) return null;
     TreeNode temp = root.left;
     root.left = root.right;
     root.right = temp;
     root.left = MirrorRecursive(root.left);
     root.right = MirrorRecursive(root.right);
     return root;
 }
Esempio n. 10
0
 public static void Test()
 {
     /*
      *   3        4
      *  / \  +   / \  => print "1 2 3 4 5 6"
      * 1   5    2   6
      */
     TreeNode tree1 = new TreeNode(3, new TreeNode(1, null, null), new TreeNode(5, null, null));
     TreeNode tree2 = new TreeNode(4, new TreeNode(2, null, null), new TreeNode(6, null, null));
     MergeAndPrint(tree1, tree2);
     Console.WriteLine();
 }
Esempio n. 11
0
 // O(N) time and O(N) space
 // recursive check BST property, narrowing the range of (min, max)
 public static bool IsBST_Recursive(TreeNode root)
 {
     return IsBST_Recursive(root, int.MinValue, int.MaxValue);
 }
Esempio n. 12
0
 // a variance of definition: A binary tree in which the depth
 // of every leaf never differ by more than 1
 public static bool IsBalaned_2(TreeNode root)
 {
     return false;
 }
Esempio n. 13
0
 // recursive version 2, time O(N), space O(N)
 // optimized version
 // combine the Depth() and Isbalanced()
 public static bool IsBalanced_loose_definition(TreeNode root, out int height)
 {
     if (root == null)
     {
         height = 0;
         return true;
     }
     int hLeft = 0;
     int hRight = 0;
     bool bal = IsBalanced_loose_definition(root.left, out hLeft)
         && IsBalanced_loose_definition(root.right, out hRight);
     height = Math.Max(hLeft, hRight) + 1;
     return bal && Math.Abs(hLeft - hRight) <= 1;
 }
Esempio n. 14
0
 // recursive version 1, time O(2^N), space O(N)
 // height balanced if (1) tree is empty, or
 // (2) its left and right children are balanced, and
 // (3) the difference of height of its left and right tree <= 1
 public static bool IsBalanced_loose_definition(TreeNode root)
 {
     return (root == null) ||
      (IsBalanced_loose_definition(root.left) && IsBalanced_loose_definition(root.right)
     && Math.Abs(Depth(root.left) - Depth(root.right)) <= 1);
 }
Esempio n. 15
0
 // this is the most strict commonly definition of balanced tree, same as balance in "self-balancing tree"
 // such balanced tree has the minimum height
 //
 // height balanced if (1) tree is empty, or
 // (2) its left subtree and right subtree are balanced
 // (3) the max and min depth of both subtrees can be more than 1
 // O(2^N) time and O(N) space
 public static bool IsBalanced(TreeNode root)
 {
     if (root == null) return true;
     if (!IsBalanced(root.left) || !IsBalanced(root.right)) return false;
     return Math.Max(MaxDepth(root.left), MaxDepth(root.right))
         - Math.Min(MinDepth(root.left), MinDepth(root.right)) <= 1;
 }
Esempio n. 16
0
 // recursive find depth
 public static int Depth(TreeNode root)
 {
     if (root == null) return 0;
     return Math.Max(Depth(root.left), Depth(root.right)) + 1;
 }
Esempio n. 17
0
 private static TreeNode BuildFromPreorderInorder_2(int[] preorder, int[] inorder,
     int inLeft, int inRight, int preIndex)
 {
     if (inLeft > inRight) return null;
     TreeNode node = new TreeNode(preorder[preIndex]);
     if (inLeft == inRight) return node;
     int inIndex = GetInorderIndex_by_search(inorder, node.value);
     node.left = BuildFromPreorderInorder(preorder, inorder, inLeft, inIndex - 1,
         preIndex + 1);
     node.right = BuildFromPreorderInorder(preorder, inorder, inIndex + 1, inRight,
         preIndex + (inIndex - inLeft));
     return node;
 }
Esempio n. 18
0
        public static void Test()
        {
            /*
            *        1
            *       / \
            *      2   3
            *     / \ /
            *    4  5 6
            *      /
            *     7
            */
            TreeNode tree1 = new TreeNode(1, new TreeNode(2,
                new TreeNode(4, null, null), new TreeNode(5,
                new TreeNode(7, null, null), null)),
                new TreeNode(3, new TreeNode(6, null, null), null));
            /*
             * Level-1: 1
             * Level-2: 2 3
             * Level-3: 4 5 6
             * Level-4: 7
             */
            PrintLevelOrder_by_two_queue(tree1);
            Console.WriteLine();
            PrintLevelOrder_by_one_queue(tree1);
            Console.WriteLine();

            /*
             * Level-4: 7
             * Level-3: 4 5 6
             * Level-2: 2 3
             * Level-1: 7
             */
            PrintLevelOrder_BottomUp(tree1);
            Console.WriteLine();
        }
Esempio n. 19
0
 // TODO
 public static void MergeAndPrint(TreeNode bst1, TreeNode bst2)
 {
 }
Esempio n. 20
0
 public static int MinDepth(TreeNode root)
 {
     if (root == null) return 0;
     //if (root != null && root.left == null && root.right == null) return 1;
     return Math.Min(MinDepth(root.left), MinDepth(root.right)) + 1;
 }
Esempio n. 21
0
 // DFS
 // for every node, swap the left subtree and the right subtree
 public static TreeNode MirrorIterative(TreeNode root)
 {
     if (root == null) return null;
     Stack<TreeNode> stack = new Stack<TreeNode>();
     stack.Push(root);
     while (stack.Count > 0)
     {
         TreeNode node = stack.Pop();
         TreeNode temp = node.left;
         node.left = node.right;
         node.right = temp;
         if (node.left != null)
             stack.Push(node.left);
         if (node.right != null)
             stack.Push(node.right);
     }
     return root;
 }
Esempio n. 22
0
        public static void Test()
        {
            /* This tree is NOT balanced!
             *        1
             *       / \
             *      2   3
             *     / \ /
             *    4  5 6
             *      /
             *     7
             */
            TreeNode tree1 = new TreeNode(1, new TreeNode(2,
                new TreeNode(4, null, null), new TreeNode(5,
                new TreeNode(7, null, null), null)),
                new TreeNode(3, new TreeNode(6, null, null), null));

            /* This tree is NOT balanced!
             *        1
             *       / \
             *      2   3
             *     /   / \
             *    4   5   6
             *   /    /    \
             *  7    8      9
             */
            TreeNode tree2 = new TreeNode(1, new TreeNode(2,
                new TreeNode(4, new TreeNode(7, null, null), null), null),
                new TreeNode(3, new TreeNode(5, new TreeNode(8, null, null), null),
                    new TreeNode(6, null, new TreeNode(9, null, null))));

            Console.WriteLine("Depth() = " + MinDepth(tree1)); // 4
            Console.WriteLine("IsBalanced_loose_definition() = " + IsBalanced_loose_definition(tree1)); // true
            Console.WriteLine("IsBalanced()= " + IsBalanced(tree1)); // false
            int depth = 0;
            Console.WriteLine("IsBalanced(out int height) = " + IsBalanced_loose_definition(tree1, out depth)); // true
            Console.WriteLine("Depth() = " + MinDepth(tree2)); // 4
            Console.WriteLine("IsBalanced_loose_definition() = " + IsBalanced_loose_definition(tree2)); // false
            Console.WriteLine("IsBalanced()= " + IsBalanced(tree2)); // false
            depth = 0;
            Console.WriteLine("IsBalanced(out int height) = " + IsBalanced_loose_definition(tree2, out depth)); // false
        }
Esempio n. 23
0
 public static void Test()
 {
     /*
      *        4                 4
      *       / \               /  \
      *      2   6     ->      6    2
      *     / \ / \           /\    /\
      *    1  3 5  7         7  5  3  1
      */
     TreeNode root = new TreeNode(4, new TreeNode(2,
         new TreeNode(1, null, null), new TreeNode(3, null, null)),
         new TreeNode(6, new TreeNode(5, null, null), new TreeNode(7, null, null)));
     Console.Write("original: ");
     TreeTraversal.LevelTraverse(root); // 4 2 6 1 3 5 7
     root = MirrorIterative(root);
     Console.Write("\nMirroring: "); // 4 6 2 7 5 3 1
     TreeTraversal.LevelTraverse(root);
     root = MirrorRecursive(root);
     Console.Write("\nMirroring twice: "); // 4 2 6 1 3 5 7
     TreeTraversal.LevelTraverse(root);
 }
Esempio n. 24
0
        public static void Test()
        {
            /* This tree is NOT balanced!
             *        1
             *       / \
             *      2   3
             *     / \ /
             *    4  5 6
             *      /
             *     7
             */
            TreeNode tree1 = new TreeNode(1, new TreeNode(2,
                new TreeNode(4, null, null), new TreeNode(5,
                new TreeNode(7, null, null), null)),
                new TreeNode(3, new TreeNode(6, null, null), null));

            MorrisTraverse(tree1);
            Console.WriteLine();
        }
Esempio n. 25
0
 public static int MaxPathSum_recursive(TreeNode root)
 {
     maxSum = int.MinValue;
     MaxPathSum_recursive(root, 0);
     return maxSum;
 }
Esempio n. 26
0
 // check if node1 is the ancestor of node2, O(N) time
 private static bool IsAncester(TreeNode node1, TreeNode node2)
 {
     if (node1 == null || node2 == null) return false;
     Stack<TreeNode> stack = new Stack<TreeNode>();
     stack.Push(node1);
     while (stack.Count > 0)
     {
         TreeNode node = stack.Pop();
         if (node.value == node2.value) return true;
         stack.Push(node.left);
         stack.Push(node.right);
     }
     return false;
 }
Esempio n. 27
0
 // one stack for DFS, one stack for path
 public static int MaxPathSum(TreeNode root)
 {
     if (root == null) return 0;
     Stack<TreeNode> stack = new Stack<TreeNode>();
     Stack<TreeNode> path = new Stack<TreeNode>();
     int sum = 0;
     int max = int.MinValue;
     stack.Push(root);
     while (stack.Count > 0)
     {
         TreeNode node = stack.Pop();
         path.Push(node);
         sum += node.value;
         if (node.left == null && node.right == null)
         {
             if (sum > max)
                 max = sum;
             do
             {
                 TreeNode p = path.Pop();
                 sum -= p.value;
             } while (stack.Count > 0 && path.Peek().right != stack.Peek());
         }
         if (node.right != null) stack.Push(node.right);
         if (node.left != null) stack.Push(node.left);
     }
     return max;
 }
Esempio n. 28
0
 private static int MaxDepth(TreeNode root)
 {
     if (root == null) return 0;
     return Math.Max(MaxDepth(root.left), MaxDepth(root.right)) + 1;
 }
Esempio n. 29
0
        public static void Test()
        {
            /*
             *        1
             *       / \
             *      2   2
             *     / \ / \
             *    6  5 5  9
             *      / /
             *     2 3
             */
            TreeNode root = new TreeNode(1, new TreeNode(2,
                new TreeNode(6), new TreeNode(5,
                new TreeNode(2), null)),
                new TreeNode(2, new TreeNode(5, new TreeNode(3), null), new TreeNode(9)));

            Console.WriteLine(MaxPathSum(root)); // 12
            Console.WriteLine(MaxPathSum_recursive(root)); // 12
        }
Esempio n. 30
0
 // a variant: bottom-up level order traversal
 public static void PrintLevelOrder_BottomUp(TreeNode root)
 {
     if (root == null) return;
     List<List<TreeNode>> result = new List<List<TreeNode>>();
     Queue<TreeNode> currentLevel = new Queue<TreeNode>();
     Queue<TreeNode> nextLevel = new Queue<TreeNode>();
     List<TreeNode> list = new List<TreeNode>();
     currentLevel.Enqueue(root);
     while (currentLevel.Count > 0)
     {
         TreeNode node = currentLevel.Dequeue();
         list.Add(node);
         if (node.left != null)
             nextLevel.Enqueue(node.left);
         if (node.right != null)
             nextLevel.Enqueue(node.right);
         if (currentLevel.Count == 0)
         {
             result.Add(list);
             list = new List<TreeNode>();
             currentLevel = nextLevel;
             nextLevel = new Queue<TreeNode>();
         }
     }
     for (int i = result.Count - 1; i >= 0; i--) // reversely print the List<List<TreeNode>>
     {
         List<TreeNode> li = result[i];
         Console.Write("Level-" + (i + 1) + ": ");
         for (int j = 0; j < li.Count; j++)
         {
             Console.Write(li[j].value + " ");
         }
         Console.WriteLine();
     }
 }