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); } }
/// <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; } } } }
/// <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); }
/// <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); }
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)); }
/* 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); } }
private static int SumOfAllNodes(BinaryNodeInt root) { if (root == null) { return(0); } else { return(root.Value + SumOfAllNodes(root.Left) + SumOfAllNodes(root.Right)); } }
/* 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; } }
/* 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); }
/// <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); }
/* 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 + " "); }
/* 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); } }
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); }
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); }
/// <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*/ } }
/// <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); }
/// <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(); } }
/// <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); } } }
// 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); } } }
/// <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); } } }
/// <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)); }
public BinaryNodeInt(int value) { this.Value = value; this.Left = this.Right = null; }
private static bool isBalanced(BinaryNodeInt root) { return(MaxDepth(root) != -1); }