예제 #1
0
        public static bool haspathSum(BinaryNodeInt node, int sum)
        {
            if (node == null)
            {
                return(sum == 0);
            }
            else
            {
                bool ans = false;

                /* otherwise check both subtrees */
                int subsum = sum - node.Value;
                if (subsum == 0 && node.Left == null && node.Right == null)
                {
                    return(true);
                }
                if (node.Left != null)
                {
                    ans = ans || haspathSum(node.Left, subsum);
                }
                if (node.Right != null)
                {
                    ans = ans || haspathSum(node.Right, subsum);
                }
                return(ans);
            }
        }
예제 #2
0
        /// <summary>
        /// 1) Create an empty stack S.
        /// 2) Initialize current node as root
        /// 3) Push the current node to S and set current = current->left until current is NULL
        /// 4) If current is NULL and stack is not empty then
        ///     a) Pop the top item from stack.
        ///     b) Print the popped item, set current = popped_item->right
        ///     c) Go to step 3.
        /// 5) If current is NULL and stack is empty then we are done.
        /// https://www.geeksforgeeks.org/inorder-tree-traversal-without-recursion/
        /// </summary>
        /// <param name="root"></param>
        private static void IterativeInOrderUsingStack(BinaryNodeInt root)
        {
            if (root == null)
            {
                return;
            }

            Stack <BinaryNodeInt> stack = new Stack <BinaryNodeInt>();

            while (root != null)
            {
                stack.Push(root);
                root = root.Left;
            }

            while (stack.Count > 0)
            {
                root = stack.Pop();
                Console.Write(root.Value + " ");
                if (root.Right != null)
                {
                    root = root.Right;

                    while (root != null)
                    {
                        stack.Push(root);
                        root = root.Left;
                    }
                }
            }
        }
예제 #3
0
        /// <summary>
        /// In fact, we could optimize this scenario by doing a breadth-first traversal (also known as
        /// level-order traversal). When we encounter the first leaf node, we immediately stop the
        /// traversal.
        /// We also keep track of the current depth and increment it when we reach the end of level.
        ///
        /// We know that we have reached the end of level when the current node is the right-most node.
        ///
        /// Compared to the recursion approach, the breadth-first traversal works well for highly
        /// unbalanced tree because it does not need to traverse all nodes. The worst case is when the
        /// tree is a full binary tree with a total of n nodes. In this case, we have to traverse all nodes.
        ///
        /// The worst case space complexity is O(n), due to the extra space needed to store current
        /// level nodes in the queue.
        /// </summary>
        /// <param name="root"></param>
        /// <returns></returns>
        private static int MinDepthBreadthFirst(BinaryNodeInt root)
        {
            if (root == null)
            {
                return(0);
            }
            Queue <BinaryNodeInt> q = new Queue <BinaryNodeInt>();

            q.Enqueue(root);
            BinaryNodeInt rightMost = root;
            int           depth     = 1;

            while (q.Count > 0)
            {
                BinaryNodeInt node = q.Dequeue();
                if (node.Left == null && node.Right == null)
                {
                    break;
                }
                if (node.Left != null)
                {
                    q.Enqueue(node.Right);
                }
                if (node.Right != null)
                {
                    q.Enqueue(node.Right);
                }
                if (node == rightMost)
                {
                    depth++;
                    rightMost = (node.Right != null) ? node.Right : node.Left;
                }
            }
            return(depth);
        }
예제 #4
0
 /// <summary>
 /// Given a binary tree, find its maximum depth.
 /// The maximum depth is the number of nodes along the longest path from the root node
 /// down to the farthest leaf node.
 ///
 //  We could solve this easily using recursion, because each of the left child and right child
 //  of a node is a sub-tree itself.We first compute the max height of left sub-tree, and then
 //  compute the max height of right sub-tree.The maximum depth of the current node is the
 //  greater of the two maximums plus one. For the base case, we look at a tree that is empty,
 //  which we return 0.
 //  Assume that n is the total number of nodes in the tree. The runtime complexity is O(n)
 //  because it traverse each node exactly once. As the maximum depth of a binary tree is
 //  O(log n), the extra space cost is O(log n) due to the extra stack space used by the
 //  recursion.
 /// </summary>
 /// <param name="root"></param>
 /// <returns></returns>
 private static int MaxDepth(BinaryNodeInt root)
 {
     if (root == null)
     {
         return(0);
     }
     return(Math.Max(MaxDepth(root.Left), MaxDepth(root.Right)) + 1);
 }
예제 #5
0
 private static bool valid(BinaryNodeInt p, int low, int high)
 {
     if (p == null)
     {
         return(true);
     }
     return((low == 0 || p.Value > low) && (high == 0 || p.Value < high) &&
            valid(p.Left, low, p.Value) &&
            valid(p.Right, p.Value, high));
 }
예제 #6
0
        /* function to print level order traversal of tree*/
        private static void PrintLevelOrder(BinaryNodeInt root)
        {
            int h = Height(root);
            int i;

            for (i = 1; i <= h; i++)
            {
                PrintGivenLevel(root, i);
            }
        }
예제 #7
0
 private static int SumOfAllNodes(BinaryNodeInt root)
 {
     if (root == null)
     {
         return(0);
     }
     else
     {
         return(root.Value + SumOfAllNodes(root.Left) + SumOfAllNodes(root.Right));
     }
 }
예제 #8
0
        /* Function to print REVERSE level order traversal a tree*/
        /// <summary>
        /// https://www.geeksforgeeks.org/reverse-level-order-traversal/
        /// </summary>
        /// <param name="root"></param>
        private static void PrintReverseLevelOrder(BinaryNodeInt root)
        {
            int h = Height(root);
            int i;

            for (i = h; i >= 1; i--)
            //THE ONLY LINE DIFFERENT FROM NORMAL LEVEL ORDER
            {
                PrintGivenLevel(root, i);
            }
        }
        private static void IterativePostOrderUsingStack(BinaryNodeInt root)
        {
            Stack <BinaryNodeInt> stack = new Stack <BinaryNodeInt>();

            // Check for empty tree
            if (root == null)
            {
                return;
            }
            stack.Push(root);

            BinaryNodeInt prev = null;

            while (stack.Count > 0)
            {
                BinaryNodeInt current = stack.Peek();

                if (prev == null || prev.Left == current || prev.Right == current)
                {
                    if (current.Left != null)
                    {
                        stack.Push(current.Left);
                    }
                    else if (current.Right != null)
                    {
                        stack.Push(current.Right);
                    }
                    else
                    {
                        stack.Pop();
                        Console.Write(current.Value + " ");
                    }
                }
                else if (current.Left == prev)
                {
                    if (current.Right != null)
                    {
                        stack.Push(current.Right);
                    }
                    else
                    {
                        stack.Pop();
                        Console.Write(current.Value + " ");
                    }
                }
                else if (current.Right == prev)
                {
                    stack.Pop();
                    Console.Write(current.Value + " ");
                }

                prev = current;
            }
        }
예제 #10
0
        /* Constructed binary tree is
         *    10
         *   /  \
         * 8     2
         * / \   /
         * 3   5 2
         */
        public static void Test()
        {
            BinaryNodeInt root = new BinaryNodeInt(10);

            root.Left       = new BinaryNodeInt(8);
            root.Right      = new BinaryNodeInt(2);
            root.Left.Left  = new BinaryNodeInt(3);
            root.Left.Right = new BinaryNodeInt(5);
            root.Right.Left = new BinaryNodeInt(2);

            Console.Write("Sum of all nodes is: " + SumOfAllNodesInBinaryTree.SumOfAllNodes(root));
        }
        public static void Test()
        {
            BinaryNodeInt root = new BinaryNodeInt(1);

            root.Left       = new BinaryNodeInt(2);
            root.Right      = new BinaryNodeInt(3);
            root.Left.Left  = new BinaryNodeInt(4);
            root.Left.Right = new BinaryNodeInt(5);

            // 1 2 4 5 3
            Console.Write("Preorder traversal of binary tree is \n");
            RecursivePostOrder(root);
            Console.Write("\n");
            IterativePostOrderUsingStack(root);
        }
예제 #12
0
        /// <summary>
        /// Algorithm Preorder(tree)
        /// 1. Visit the root.
        /// 2. Traverse the left subtree, i.e., call Preorder(left-subtree)
        /// 3. Traverse the right subtree, i.e., call Preorder(right-subtree)
        /// https://www.geeksforgeeks.org/tree-traversals-inorder-preorder-and-postorder/
        /// </summary>
        private static void RecursivePreOrder(BinaryNodeInt node)
        {
            if (node == null)
            {
                return;
            }

            /* first print data of node */
            Console.Write(node.Value + " ");

            /* then recur on left sutree */
            RecursivePreOrder(node.Left);

            /* now recur on right subtree */
            RecursivePreOrder(node.Right);
        }
예제 #13
0
        /* Given a binary tree, print its nodes in inorder*/
        /// <summary>
        /// Algorithm Inorder(tree)
        /// 1. Traverse the left subtree, i.e., call Inorder(left-subtree)
        /// 2. Visit the root.
        /// 3. Traverse the right subtree, i.e., call Inorder(right-subtree)
        /// https://www.geeksforgeeks.org/tree-traversals-inorder-preorder-and-postorder/
        /// </summary>
        /// <param name="node"></param>
        private static void RecursiveInOrder(BinaryNodeInt node)
        {
            if (node == null)
            {
                return;
            }

            /* first recur on left child */
            RecursiveInOrder(node.Left);

            /* then print the data of node */
            Console.Write(node.Value + " ");

            /* now recur on right child */
            RecursiveInOrder(node.Right);
        }
        /// <summary>
        /// Algorithm Postorder(tree)
        /// 1. Traverse the left subtree, i.e., call Postorder(left-subtree)
        /// 2. Traverse the right subtree, i.e., call Postorder(right-subtree)
        /// 3. Visit the root.
        /// https://www.geeksforgeeks.org/tree-traversals-inorder-preorder-and-postorder/
        /// </summary>
        /// <param name="node"></param>
        private static void RecursivePostOrder(BinaryNodeInt node)
        {
            if (node == null)
            {
                return;
            }

            // first recur on left subtree
            RecursivePostOrder(node.Left);

            // then recur on right subtree
            RecursivePostOrder(node.Right);

            // now deal with the node
            Console.Write(node.Value + " ");
        }
예제 #15
0
 /* Print nodes at the given level */
 private static void PrintGivenLevel(BinaryNodeInt root, int level)
 {
     if (root == null)
     {
         return;
     }
     if (level == 1)
     {
         Console.Write(root.Value + " ");
     }
     else if (level > 1)
     {
         PrintGivenLevel(root.Left, level - 1);
         PrintGivenLevel(root.Right, level - 1);
     }
 }
예제 #16
0
        private static void ReverseTree(BinaryNodeInt root)
        {
            if (root == null)
            {
                return;
            }

            // swap root.left with root.right
            BinaryNodeInt temp = root.Right;

            root.Right = root.Left;
            root.Left  = temp;

            ReverseTree(root.Left);

            ReverseTree(root.Right);
        }
예제 #17
0
        public static void Test()
        {
            BinaryNodeInt root = new BinaryNodeInt(1);

            root.Left       = new BinaryNodeInt(2);
            root.Right      = new BinaryNodeInt(3);
            root.Left.Left  = new BinaryNodeInt(4);
            root.Left.Right = new BinaryNodeInt(5);

            Console.Write("level traversal of binary tree is \n");
            PrintLevelOrder(root);
            Console.Write("\n");
            PrintLevelOrderUsingQueue(root);
            Console.Write("\n");
            PrintReverseLevelOrder(root);
            Console.Write("\n");
            PrintReverseLevelOrderUsingQueueStack(root);
        }
예제 #18
0
        /// <summary>
        /// 1. Initialize current as root
        /// 2. While current is not NULL
        /// If current does not have left child
        ///     a) Print current’s data
        ///     b) Go to the right, i.e., current = current->right
        /// Else
        ///     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
        /// https://www.geeksforgeeks.org/inorder-tree-traversal-without-recursion-and-without-stack/
        /// </summary>
        /// <param name="root"></param>
        private static void IterativeInOrderUsingNonStack(BinaryNodeInt root)
        {
            if (root == null)
            {
                return;
            }

            BinaryNodeInt current, pre;

            current = root;
            while (current != null)
            {
                if (current.Left == null)
                {
                    Console.Write(current.Value + " ");
                    current = current.Right;
                }
                else
                {
                    /* Find the inorder predecessor of current */
                    pre = current.Left;
                    while (pre.Right != null && pre.Right != current)
                    {
                        pre = pre.Right;
                    }

                    /* Make current as right child of its inorder predecessor */
                    if (pre.Right == null)
                    {
                        pre.Right = current;
                        current   = current.Left;
                    }

                    /* Revert the changes made in if part to restore the
                     * original tree i.e.,fix the right child of predecssor*/
                    else
                    {
                        pre.Right = null;
                        Console.Write(current.Value + " ");
                        current = current.Right;
                    } /* End of if condition pre->right == NULL */
                }     /* End of if condition current->left == NULL*/
            }
        }
예제 #19
0
        /// <summary>
        /// We could avoid the recalculation by passing the depth bottom-up.We use a sentinel value –1
        /// to represent that the tree is unbalanced so we could avoid unnecessary calculations.
        ///
        /// In each step, we look at the left subtree’s depth(L), and ask: “Is the left subtree
        /// unbalanced?” If it is indeed unbalanced, we return –1 right away.Otherwise, L represents
        /// the left subtree’s depth. We then repeat the same process for the right subtree’s depth (R).
        ///
        /// We calculate the absolute difference between L and R.If the subtrees’ depth difference is
        /// less than one, we could return the height of the current node, otherwise return –1 meaning
        /// the current tree is unbalanced.
        /// </summary>
        /// <param name="root"></param>
        /// <returns></returns>
        private static int MaxDepth(BinaryNodeInt root)
        {
            if (root == null)
            {
                return(0);
            }
            int L = MaxDepth(root.Left);

            if (L == -1)
            {
                return(-1);
            }
            int R = MaxDepth(root.Right);

            if (R == -1)
            {
                return(-1);
            }
            return((Math.Abs(L - R) <= 1) ? (Math.Max(L, R) + 1) : -1);
        }
예제 #20
0
        /// <summary>
        /// The idea is to use a stack to get the reverse level order.
        /// If we do normal level order traversal and instead of printing a node,
        /// push the node to a stack and then print contents of stack, we get “5 4 3 2 1” for above example tree,
        /// but output should be “4 5 2 3 1”.
        /// So to get the correct sequence (left to right at every level),
        /// we process children of a node in reverse order,
        /// we first push the right subtree to stack, then left subtree.
        /// https://www.geeksforgeeks.org/reverse-level-order-traversal/
        /// </summary>
        /// <param name="root"></param>
        private static void PrintReverseLevelOrderUsingQueueStack(BinaryNodeInt node)
        {
            Stack <BinaryNodeInt> S = new Stack <BinaryNodeInt>();
            Queue <BinaryNodeInt> Q = new Queue <BinaryNodeInt>();

            Q.Enqueue(node);

            // Do something like normal level order traversal order.Following
            // are the differences with normal level order traversal
            // 1) Instead of printing a node, we push the node to stack
            // 2) Right subtree is visited before left subtree
            while (Q.Count > 0)
            {
                /* Dequeue node and make it root */
                node = Q.Peek();
                Q.Dequeue();
                S.Push(node);

                /* Enqueue right child */
                if (node.Right != null)
                {
                    // NOTE: RIGHT CHILD IS ENQUEUED BEFORE LEFT
                    Q.Enqueue(node.Right);
                }

                /* Enqueue left child */
                if (node.Left != null)
                {
                    Q.Enqueue(node.Left);
                }
            }

            // Now pop all items from stack one by one and print them
            while (S.Count > 0)
            {
                node = S.Peek();
                Console.Write(node.Value + " ");
                S.Pop();
            }
        }
예제 #21
0
        /// <summary>
        /// Algorithm:
        /// There are basically two functions in this method.One is to print all nodes at a given level(printGivenLevel),
        /// and other is to print level order traversal of the tree(printLevelorder).
        /// printLevelorder makes use of printGivenLevel to print nodes at all levels one by one starting from root.
        /// /*Function to print level order traversal of tree*/
        /// printLevelorder(tree)
        /// for d = 1 to height(tree)
        ///     printGivenLevel(tree, d);
        /// /*Function to print all nodes at a given level*/
        /// printGivenLevel(tree, level)
        /// if tree is NULL then return;
        /// if level is 1, then
        ///     print(tree->data);
        /// else if level greater than 1, then
        ///     printGivenLevel(tree->left, level-1);
        ///     printGivenLevel(tree->right, level-1);
        /// </summary>
        /// <param name="root"></param>
        /// <returns></returns>

        /* Compute the "height" of a tree -- the number of
         * nodes along the longest path from the root node
         * down to the farthest leaf node.*/
        private static int Height(BinaryNodeInt root)
        {
            if (root == null)
            {
                return(0);
            }
            else
            {
                /* compute  height of each subtree */
                int lheight = Height(root.Left);
                int rheight = Height(root.Right);

                /* use the larger one */
                if (lheight > rheight)
                {
                    return(lheight + 1);
                }
                else
                {
                    return(rheight + 1);
                }
            }
        }
예제 #22
0
        // Time Complexity: O(n^2) in worst case. For a skewed tree,
        // printGivenLevel() takes O(n) time where n is the number of nodes in the skewed tree.
        // So time complexity of printLevelOrder() is O(n) + O(n-1) + O(n-2) + .. + O(1) which is O(n^2).

        // Method 2: Use Queue
        ///Algorithm:
        ///For each node, first the node is visited and then it’s child nodes are put in a FIFO queue.
        ///
        /// printLevelorder(tree)
        /// 1) Create an empty queue q
        /// 2) temp_node = root /*start from root*/
        /// 3) Loop while temp_node is not NULL
        ///     a) print temp_node->data.
        ///     b) Enqueue temp_node’s children(first left then right children) to
        ///     c) Dequeue a node from q and assign it’s value to temp_node

        /// <summary>
        /// Given a binary tree. Print its nodes in level order using array for implementing queue
        /// </summary>
        private static void PrintLevelOrderUsingQueue(BinaryNodeInt root)
        {
            Queue <BinaryNodeInt> queue = new Queue <BinaryNodeInt>();

            queue.Enqueue(root);
            while (queue.Count > 0)
            {
                BinaryNodeInt tempNode = queue.Dequeue();
                Console.Write(tempNode.Value + " ");

                /*Enqueue left child */
                if (tempNode.Left != null)
                {
                    queue.Enqueue(tempNode.Left);
                }

                /*Enqueue right child */
                if (tempNode.Right != null)
                {
                    queue.Enqueue(tempNode.Right);
                }
            }
        }
예제 #23
0
        /// <summary>
        /// PreOrder: root - left - right
        /// To convert an inherently recursive procedures to iterative,
        /// we need an explicit stack. Following is a simple stack based iterative process to print Preorder traversal.
        /// 1) Create an empty stack nodeStack and push root node to stack.
        /// 2) Do following while nodeStack is not empty.
        /// ….a) Pop an item from stack and print it.
        /// ….b) Push right child of popped item to stack
        /// ….c) Push left child of popped item to stack
        ///
        /// Right child is pushed before left child to make sure that left subtree is processed first.
        /// https://www.geeksforgeeks.org/iterative-preorder-traversal/
        /// </summary>
        /// <param name="root"></param>
        private static void IterativePreOrderUsingStack(BinaryNodeInt root)
        {
            // Base Case
            if (root == null)
            {
                return;
            }

            // Create an empty stack and push root to it
            Stack <BinaryNodeInt> nodeStack = new Stack <BinaryNodeInt>();

            nodeStack.Push(root);

            /* Pop all items one by one. Do following for every popped item
             *  a) print it
             *  b) push its right child
             *  c) push its left child
             * Note that right child is pushed first so that left is processed first */
            while (nodeStack.Count > 0)
            {
                // Pop the top item from stack and print it
                BinaryNodeInt node = nodeStack.Peek();
                Console.Write(node.Value + " ");
                nodeStack.Pop();

                // Push right and left children of the popped node to stack
                if (node.Right != null)
                {
                    nodeStack.Push(node.Right);
                }

                if (node.Left != null)
                {
                    nodeStack.Push(node.Left);
                }
            }
        }
예제 #24
0
 /// <summary>
 ///         10
 ///        /  \
 ///       5    15
 ///            / \
 ///           6   20
 /// We can avoid examining all nodes of both subtrees in
 /// each pass by passing down the low and high limits from the parent to its children.
 /// Refer back to the binary tree (1) above.As we traverse down the tree from node(10) to
 /// right node(15), we know for sure that the right node’s value fall between 10 and +∞.
 /// Then, as we traverse further down from node(15) to left node(6), we know for sure that
 /// the left node’s value fall between 10 and 15. And since(6) does not satisfy the above
 /// requirement, we can quickly determine it is not a valid BST.
 /// </summary>
 /// <param name="root"></param>
 /// <returns></returns>
 private static bool isValidBST(BinaryNodeInt root)
 {
     return(valid(root, 0, 0));
 }
예제 #25
0
 public BinaryNodeInt(int value)
 {
     this.Value = value;
     this.Left  = this.Right = null;
 }
예제 #26
0
 private static bool isBalanced(BinaryNodeInt root)
 {
     return(MaxDepth(root) != -1);
 }