Have been searching on web for more than 5 hours and cant find a general BT Preorder visit pseudocode.
Thanks in advance.
I just find short pseudocodes like this
Algorithm postorder(T, v)
Input: A binary tree T and a node v of T.
Output: Depends on the action performed on a visit to a node.
if T.hasLeft(v)
postorder(T, T.left(v)) // recursively traverse left subtree
if T.hasRight(v)
postorder(T, T.right(v)) // recursively traverse right subtree
visit node v
The difference between preorder, inorder, and postorder is simply the order in which the nodes are visited, relative to the children:
You posted this:
Algorithm postorder(T, v)
Input: A binary tree T and a node v of T.
Output: Depends on the action performed on a visit to a node.
if T.hasLeft(v)
postorder(T, T.left(v)) // recursively traverse left subtree
if T.hasRight(v)
postorder(T, T.right(v)) // recursively traverse right subtree
visit node v
To change among the behaviors, change the order of execution. Here's some generic code:
AnyOrder:
AnyOrder(T, v, order)
if order is 'pre'
visit(v)
AnyOrder(T, T.left(v), order)
if order is 'in'
visit(v)
AnyOrder(T, T.right(v), order)
if order is 'post'
visit(v)
Related
I am facing a couple of doubts in tree data structure.
1) Is tree traversing (Preorder, Inorder, Postorder) possible in all types of trees or only binary trees.
2) If the first point is valid, then can we simply Inorder traverse a tree and store the elements in an array.
And then by using that array can we find predecessor and successor, as elements coming before and after a given element.
1.
Tree traversing (Preorder, Inorder, Postorder) possible in all types of trees
not only in binary trees.
every tree contains child nodes.( binary tree 2, ternary tree 3 etc).
We need to define our own way of traversing the trees.
lets take example of ternary tree.
Preorder : visit(root.data) - >root.left -> root.middle -> root.right
postorder: root.left -> root.middle - > root.right -> visit(root.data)
inorder : root.left -> root.middle -> visit(root.data) - > root.right
Preorder : visit all k child nodes( from left to right) after first visiting root node.
Postorder : visit all k child nodes (from left to right) before visiting root node.
Inorder : visit k/2 child nodes( from left to right) and visit root node then visit remaining k/2 child nodes.
we can store the tree in an array by inorder traversing.
we can find the predecessor and successor from that array by how we did inorder traversal.
for a binary tree, predecessor = left child, successor = right child
for ternary tree, predecessor = left child or middle child , successor = middle child or right child. ( we have to specify it based on our requirement)
Hi I'm a bit confused with this tree and need help in figuring out if I'm choosing the right answer.
Tree :
A
/ \
B C
/ \
D E
Lets do the traversal first:
In-order : BADCE
Pre-Order : ABCDE
Post-Order : BDECA
Questions:
Which of the following traversals yields BADEC?
a. only in-order
b. only level order
c. only post-order
d. only pre-order
e. pre-order and level order
f. in-order and level order
g. none of the above
Answer g
Which of the following is a post-order traversal of the BST?
a. ACEDB
b. ABDCE
c. BDECA
d. EDCBA
e. BADCE
f. BADEC
g. one of the above
Answer g
Can someone please confirm if I have done the traversal correctly and have chosen the correct answer for both question.
Thanks
The three traversal algorithms is a recursive algorithm. This means that in order to traverse the entire tree rooted at node A, the algorithm will split and finish the task in three parts:
traverse the subtree rooted at B (A's left child)
traverse the subtree rooted rooted at C (A's right child)
traverse/visit A itself
The order of the three tasks depends on which order you use:
- In-order (Left, Root, Right) does task1, task3, and then task2. - Pre-order (Root, Left, Right) does task3, task1, and then task2. - Post-order (Left, Right, Root) does task1, task2, and then task3
Continue the recursive algorithm: to traverse the subtree rooted at B, it will split the task further and traverse the subtree rooted at B's left child, the subtree rooted at B's right child, and then B.
The "splitting task" continues until the subtree to traverse contains only one root node. In this case, the algorithm visits the root node and returns to the remaining sub-tasks. Same thing happens to the subtree rooted at C, A's right child.
Here are the detailed steps to traverse the tree in the question in 3 different orders and to answer the questions using the traversal results:
In-order traversal (Left, Root, Right):
traverse subtree rooted at B
visit B
visit A
traverse subtree rooted at C
traverse C's left subtree
visit D
visit C
traverse C's right subtree
visit E
In-order: BADCE
Pre-order traversal (Root, Left, Right)
visit A
traverse subtree rooted at B
visit B
traverse subtree rooted at C
visit C
traverse C's left subtree
visit D
traverse C's right subtree
visit E
Pre-order: ABCDE
Post-order traversal (Left, Right, Root)
traverse subtree rooted at B
visit B
traverse subtree rooted at C
traverse C's left subtree
visit D
traverse C's right subtree
visit E
visit C
visit A
Post-order: BDECA
You can check if your traversal results are the same as above.
Looking at the traversal results, we know that the answer to your question 1 is g, and the answer to your question 2 is c.
A binary tree is given and we have to count the number of binary search trees in it.Every leaf node is a BST
I used the following approach.
for every node in bt check if it is bst or not
The time complexity for above approach is O(n2).How can we do it in an efficient way O(n).
If I understood the question correctly, this can be solved as follows; one would aim at counting the number of nodes which are the root of a binary seach tree. As already remarked, every leaf is trivially the root of a binary search tree. A non-leaf node a is the root of a binary search if and only if the left child of a is a binary search tree, the right child of b is the root of a binary search tree and the maximum over all values under the left child of a is not greater than the value of a and the minumum over all values under the right child of a are larger or equal to the value of a. Evaluation of this property can be done by a recursive evaluation which visits every node exactly once, which results in a linear runtime bound.
A straightforward recursive traversal of the tree returning a few extra pieces of data may help manage it in O(n) time, n being the number of nodes. Below you can find an implementation in Python.
numBST = 0
def traverse(root):
global numBST
leftComplies = True
rightComplies = True
rootRange = [root.val, root.val]
if root.left != None:
leftResult = traverse(root.left)
leftComplies = leftResult[0] and leftResult[1][1] < root.val
rootRange[0] = leftResult[1][0]
if root.right != None:
rightResult = traverse(root.right)
rightComplies = rightResult[0] and rightResult[1][0] > root.val
rootRange[1] = rightResult[1][1]
if leftComplies and rightComplies:
numBST += 1
return (leftComplies and rightComplies, rootRange)
After you run traverse with root of the binary tree as parameter, numBST will contain the number of BSTs within the root.
The function traverse given above recursively traverses the tree root of which is given to it as a parameter. For each node V, if V has a left child L, it recursively traverses the left child and returns some data. Specifically, it returns a list of length 2. The first element in the list is a boolean value indicating whether the left subtree rooted in L is a BST. Second element of the returned list contains another list containing the smallest and the largest value, respectively, in the subtree rooted in L.
For the tree rooted in V to be a BST, the subtree rooted in L must also be a BST AND the largest value in the subtree rooted in L(hence all the values in that subtree) must be smaller than the value stored in V. So after recursively calling traverse for L, we check the returned data to find out if these conditions are satisfied.
Similarly, if there is a right child R of V, it is recursively traversed. To be a BST, the tree rooted in V must also satisfy the condition that the tree rooted in R is a BST AND the smallest node of subtree rooted in R(hence all the nodes in that subtree) contains a value that is larger than the value stored in V.
If all these conditions are satisfied, the tree rooted in V can be considered as a BST and the result, stored in numBST, is updated accordingly. Note that we also update the smallest and largest values stored in V as we recursively traverse its children L and R, and perform the checks mentioned above, so that we pass the correctly updated values to the higher levels of recursion.
Just wanted to know how efficient is the below algorithm to find the lowest common ancestor of two nodes in a binary search tree.
Node getLowestCommonAncestor (Node root, Node a, Node b) {
Find the in-order traversal of Node root.
Find temp1 = the in-order successor of Node a.
Find temp2 = the in-order successor of Node b.
return min (temp1, temp2);
}
Searching for the lowest common ancestor in a binary search tree is simpler than that: observe that the LCA is the node where the searches for item A and item B diverge for the first time.
Start from the root, and search for A and B at the same time. As long as both searches take you in the same direction, continue the search. Once you arrive at the node such that searching for A and B take you to different subtrees, you know that the current node is the LCA.
A node at the bottom of a large binary search trees can have an in-order successor close to it, for instance if it is the left child of a node, its in-order successor is its parent.
Two nodes descending from different children of the root will have the root as their least common ancestor, no matter where they are, so I believe that your algorithm gets this case wrong.
This is a discussion of efficient LCA algorithms (given time to build a preparatory data structure) at http://en.wikipedia.org/wiki/Lowest_common_ancestor, with pointers to code.
An inefficient but simple way of finding the LCA is as follows: in the tree keep pointers from children to parents and a note of the depth of each node. Given two nodes, move up from the deepest one until the depth if the same. If you are pointing at the other node, it is the LCA. Otherwise move up one step from each node and check again, and so on, until you meet at the LCA.
Finding LCA of BST is straight:
Find the node for which node1 and node2 are present on different
sides. But if the node1 is an ancestor of node2 than also we will
have to return node1. Below code implements this algo.
TreeNode<K> commonAncestor(TreeNode t, K k1, K k2){
if(t==null) return null;
while(true)
{
int c1=t.k.compareTo(k1);
int c2=t.k.compareTo(k2);
if(c1*c2<=0)
{
return t;
}
else
{
if(c1<0)
{
t = t.right;
}
else
{
t = t.left;
}
}
}
}
I need an algorithm for returning the successor node of some arbitrary node of the
given binary search tree.
To give you an answer with the same level of detail as your question: Go up until going right is possible, and then left until you reach a leaf.
There are two general approaches:
If your binary tree nodes have pointers to their parent node, then you can traverse directly from the node to the successor node. You will have to determine how to use the parent pointers to do the traversal.
If your binary tree nodes do not have parent pointers, then you will have to do an inorder traversal of the tree starting at the root (presumably you have a root node pointer) and return the next node after the given node.
You need to maintain a zipper as you descend the tree. A zipper is simply a list of the nodes you have traversed, and for each an indication of whether you next went left or right.
It allows you to travel back up in the tree even if there aren't any pointers from children to parents.
The algorithm for successor is to go back (up in the zipper) as long as you were coming from the left, then go right once, and then descend to the leftmost child.
It's easier with a figure...
The successor of a node implies you are looking for an inorder successor.
The following method helps you determine the inorder successor WITHOUT ANY PARENT NODE OR EXTRA SPACE NON-RECURSIVELY
struct node * inOrderSuccessor(struct node *root, struct node *n)
{
//*If the node has a right child, return the smallest value of the right sub tree*
if( n->right != NULL )
return minValue(n->right);
//*Return the first ancestor in whose left subtree, node n lies*
struct node *succ=NULL;
while(root)
{
if(n->datadata < root->data)
{
succ=root; root=root->left;
}
else if(n->data > root->data)
root=root->right;
else break;
}
return succ;
}
I'm quite certain this is right. Do correct me if I am wrong. Thanks.