How to verify if a given tree is a Binary Search Tree or not [duplicate] - algorithm

This question already has answers here:
How do you validate a binary search tree?
(33 answers)
Closed 8 years ago.
I wanted to know if a given binary tree is a binary search tree or not.
I don't know How to do that?
The only thing I know is that the inorder traversal of BST will gives you ascending order output.
So, is this the only condition we need to verify or is there anything else we are suppose to check.
In case if there are some other necessary conditions to be checked, What are they? and why those conditions are necessary to be checked? Because, I think, INORDER traversal itself can tell you easily if the given tree is BST or not.

Yes, if inorder traversal of the tree gives you a strictly monotonic list of values that is sufficient to determine that the tree is a BST.

By definition of Binary search tree, if every node of the binary tree satisfy the following conditions then it is a Binary Search Tree:
The left subtree of a node should contain only nodes with keys less than the node’s key
The right subtree of a node should contain only nodes with keys greater than the node’s key
Both the left and right subtrees must also be binary search trees.
All the above conditions are verified if the inorder traversal is in ascending order.

Actually - it is not enough to just do an in order traversal - you also need to verify that each node's value follows the rules of the tree. In the case of a BST, the left child value is less than the node value and the right child value is greater than the node value. Here is a recursive example in Java.
private static boolean isBST(Node current, Comparable more, Comparable less) {
if (current == null)
return true;
if (less != null && current.value.compareTo(less) > 0)
return false;
if (more != null && current.value.compareTo(more) < 0)
return false;
return isBST(current.left, more, current.value) &&
isBST(current.right, current.value, less);
}
public static boolean isBST(BinarySearchTree tree) {
return isBST(tree.getRoot(), null, null);
}

While doing In-Order traversal, we can keep track of previously visited node
Code:
bool isBST(struct node* root)
{
static struct node *prev = NULL;
// traverse the tree in inorder fashion and keep track of prev node
if (root)
{
if (!isBST(root->left))
return false;
// Allows only distinct valued nodes
if (prev != NULL && root->data <= prev->data)
return false;
prev = root;
return isBST(root->right);
}
return true;
}

A simple but elegant recursive solution in Java:
public static boolean isBST(TreeNode node, int leftData, int rightData)
{
if (node == null) return true;
if (node.getData() > leftData || node.getData() <= rightData) return false;
return (isBST(node.left, node.getData(), rightData)
&& isBST(node.right, leftData, node.getData()));
}
The initial call to this function can be something like this:
if (isBST(root, Integer.MAX_VALUE, Integer.MIN_VALUE))
System.out.println("This is a BST.");
else
System.out.println("This is NOT a BST!");
Essentially we keep creating a valid range (starting from [ MIN_VALUE, MAX_VALUE]) and keep shrinking it down foe each node as we go down recursively.
Source: http://exceptional-code.blogspot.com/2011/08/binary-search-trees-primer.html

Related

What are some algorithms for comparing the differences between two trees?

I'm looking to find the differences while comparing two tree structures.
The nodes will be strings. And I would like to capture at what level of the tree it is occurring.
For example finding the differences between these two trees:
What about a simple hash! List all values from root to leaf of the first tree and hash them, then list all values from root to leaf of the second tree and compare to the first one with O(1) time complexity. One can split the second tree (i.g based on the first layer) and use multi thread. In python, just put them on a set, and it's all done; or hash both of them and do a .difference()
The basic idea is to traverse the both tree level by level. Once you find,
the nodes are not the same
or
the nodes are not samely structured
means you found a difference here! now you can mark the level or the node, whatever you want.
PSEDOCODE:
function getDiff(Tree root, Tree root1){
Queue queue->push(root);
Queue queue1->push(root1);
level = 1;
while(queue->size() != 0 && queue1->size() != 0){
if(queue->size() != queue1->size()) {
PRINT: "THE TREE AREN'T IN SAME STRUCTURE :/";
return;
}
size = queue->size();
/* traversing both trees level-by-level */
while(size-- > 0){
Tree temp = queue->peek();
Tree temp1 = queue1->peek();
queue->pop();
queue1->pop();
if(!temp->node != temp1->node) {
PROCESS: level;
}
if(temp->left != null && temp1->left != null) {
queue->push(temp->left);
queue1->push(temp1->left);
}
if(temp->right!= null && temp1->right!= null) {
queue->push(temp->right);
queue1->push(temp1->right);
}
}
/* increase level */
level += 1;
}
}
NOTE: CHANGE THE PSEDOCODE INTO YOUR FAVOURITE LANGUAGE :)

Is pre-order traversal a depth-first method?

Is pre-order traversal a depth-first algorithm? I'm using it in my search below.I have included the code below.
public bool DFS1(int value, BSTNode root)
{ // Pre-order search
if (root == null)
return false;
if (root.data == value)
{
Console.WriteLine("found");
return true;
}
DFS1(value, root.left); //vist the left node
return DFS1(value, root.right); // vist the right node.
}
Yes, it is depth-first: you will complete the left sub-tree completely before you look at the original root's right node. However, you need to consider the result from that left search. At the moment, this will return true iff the rightmost node has the target value.
return DFS1(value, root.left) or
DFS1(value, root.right)
Most compilers will optimize this (short-circuit), so that if the left side returns true, the right will not execute. If not, you can write it yourself:
if (DFS1(value, root.left))
return true;
else
return DFS1(value, root.right);

How do i calculate space complexity for checking if binary search tree is balanced?

I want to check if binary search tree provided to me is balanced or not.
Since tree already exists in memory, there is no additional storage needed while checking if tree is balanced when traversing through nodes.
So I assume space complexity would be O(1).
Is it correct?
// Definition for binary tree
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
public class Solution {
public boolean isBalanced(TreeNode root) {
if (root == null)
return true;
if (getHeight(root) == -1)
return false;
return true;
}
public int getHeight(TreeNode root) {
if (root == null)
return 0;
int left = getHeight(root.left);
int right = getHeight(root.right);
if (left == -1 || right == -1)
return -1;
if (Math.abs(left - right) > 1) {
return -1;
}
return Math.max(left, right) + 1;
}
}
Your algorithm is O(height) space, not O(1) - you need to store 1 recursive function call in memory for every node as you recurse down the tree, and you can never go deeper than O(height) in the tree (before you return and can get rid of the already-fully-processed nodes).
For a tree like:
(Image reference - Wikipedia)
Your calls will go like this:
getHeight(8)
getHeight(3)
getHeight(1)
getHeight(6)
getHeight(4)
getHeight(7)
getHeight(10)
getHeight(14)
getHeight(13)
Here, getHeight(8) calls getHeight(3), which calls getHeight(1) and getHeight(6), etc.
After we've finished calling the function for 1 (returning the result to the call for 3), we don't need to keep that in memory any more, thus the maximum number of calls that we keep in memory is equal to the height of the tree.
It can be done in O(1) space, but it's fairly complicated and really slow (much slower than the O(n) that your solution takes).
The key is that we have a binary search tree, so, given a node, we'd know whether that node is in the left or right subtree of any ancestor node, which we can use to determine the parent of a node.
I may create a separate Q&A going into a bit more details at some point.

Print leaf nodes in a binary tree right to left?

I'm looking for an answer for this:
Find the pseudo code of printing the leaf nodes in a binary tree, from
right to left.
I would be glad to hear some ideas. A hint (not a full solution, of course) or a link to a related topic that could assist me in understanding this issue would be helpful.
Perform a depth-first traversal of the tree, handling the right sub-trees first and printing only the leaf nodes.
The easiest way to implement this is with a recursive function.
void printLeafNodes(BinaryTreeNode* treePtr) {
if(treePtr.leftChild == null && treePtr.rightChild == null) {
//This is a leaf node; print its value
} else {
//Recurse on right subtree
if(treePtr.rightChild != null) {
printLeafNodes(treePtr.rightChild);
}
//Recurse on left subtree
if(treePtr.leftChild != null) {
printLeafNodes(treePtr.leftChild);
}
}
}
This page is pretty helpful for visualizing the solution: Tree Traversal.
void in(node* root){
if(root)
{
if(!root->left && !root->right)
cout<<root->data<<endl;
in(root->left);
in(root->right);
} }
You can do something like this(code in C++).
The idea behind this code is, do inorder traversal/ postorder traversal & check if the left & right children are NULL or not. If it's Null it means it's a leaf node.
You would need to use a recursive method by starting out with passing the method the top level node of a binary tree.
In the pseudocode, I'm assuming that each node is defined with "right" and "left" members that themselves are nodes and a "name" property, to print something about the node. The method could look like this, in no particular language since you said pseudocode:
function processNode(parent) {
if(parent.right = null AND parent.left = null)
print parent.name
if(parent.right <> null)
processNode(parent.right)
if(parent.left <> null)
processNode(parent.left)
}
Then you would start out with:
processNode(topNode)
Perform in-order traversal and add only leaf nodes to the list of visited nodes.
Revert the list.
Or
Actually when creating the list in step one keep adding node at the head and let it point to previous node(rather than previous node pointing to new node).
Print leaf nodes while doing the level order traversal in reverse order excluding the nodes which are not leaf.
Do Inoder/Preorder/postorder But for Right Child First Then go to left Child
void postOrder(Node* root)
{
if(root==NULL)
return;
postOrder(root->right);
postOrder(root->left);
if(root->left==NULL && root->right==NULL)
cout << root->data <<" ";
}
Presumably you know how to traverse a binary tree in order using recursion.
void visit(Node node) {
if(node.hasLeft()) {
visit(node.getLeft());
}
handleValue(node.value); // print or whatever
if(node.hasRight()) {
visit(node.getRight());
}
}
You'll notice that when you do this, you're already handling the leaves in left-to-right order, in addition to handling non-leaf nodes.
To visit right-to-left, just reverse the order of the statements -- so visit the right, then handle the value, then visit the left.
To print only leaf nodes, you just need to put an if statement around handleValue, telling it to only output if the node is a leaf. A node is a leaf if it has neither a left nor right child node.
python code
def Reverse_print(self):
if self.right:
self.right.Reverse_print()
print(self.data),
if self.left:
self.left.Reverse_print()
it is recursion , it goes always right until there is no right
then at last right it go back to the root print it then print left
so actually you are printing from biggest value to lowest
then back and so the same thing
then back and so the same thing
then back and so the same thing
bla...blaa..blaa
I know that I am resurrecting an old thread but I think that it may help others viewing this thread. If you are talking about interview question, i think that the recursive answer is only a small part of the answer and the interviewer will like to hear the iterative approach as well. The right to left traversal (printing) is not a regular pre/post/inorder traversals that described in wiki. The main idea here is that you need to go right as long as you can and start printing from the far right node first, then its parent and only then the left subtree.
Recursive:
printRightToLeft(Node root){
if (root == null)
return;
// You can check root.right and root.left for null before calling the
// printRightToLeft function to avoid pushing unneeded data to recursion
// call stack.
printRightToLeft(root.right);
if (root.right == null && root.left == null)
print(root);
printRightToLeft(root.left);
}
Iterative:
printRightToLeft(Node root){
if (root == null)
return;
Stack s = new Stack();
s.push(root);
while(!s.isEmpty()){
Node n = s.top();
if (n.right != null && !n.visited){
s.push(n.right);
n.visited = true;
} else {
s.pop();
if (n.right == null && n.left == null)
print(n);
if (n.left != null)
s.push(n.left);
}
}

Finding if a Binary Tree is a Binary Search Tree [duplicate]

This question already has answers here:
How do you validate a binary search tree?
(33 answers)
Closed 8 years ago.
Today I had an interview where I was asked to write a program which takes a Binary Tree and returns true if it is also a Binary Search Tree otherwise false.
My Approach1: Perform an in-order traversal and store the elements in O(n) time. Now scan through the array/list of elements and check if element at ith index is greater than element at (i+1)th index. If such a condition is encountered, return false and break out of the loop. (This takes O(n) time). At the end return true.
But this gentleman wanted me to provide an efficient solution. I tried but I was unsuccessful, because to find if it is a BST I have to check each node.
Moreover he was pointing me to think over recursion.
My Approach 2: A BT is a BST if for any node N N->left is < N and N->right > N , and the in-order successor of left node of N is less than N and the in-order successor of right node of N is greater than N and the left and right subtrees are BSTs.
But this is going to be complicated and running time doesn't seem to be good. Please help if you know any optimal solution.
It's a pretty well-known problem with the following answer:
public boolean isValid(Node root) {
return isValidBST(root, Integer.MIN_VALUE,
Integer.MAX_VALUE);
}
private boolean isValidBST(Node node, int l, int h) {
if(node == null)
return true;
return node.value > l
&& node.value < h
&& isValidBST(node.left, l, node.value)
&& isValidBST(node.right, node.value, h);
}
The recursive call makes sure that subtree nodes are within the range of its ancestors, which is important. The running time complexity will be O(n) since every node is examined once.
The other solution would be to do an inorder traversal and check if the sequence is sorted, especially since you already know that a binary tree is provided as an input.
The answer provided by #Dhruv is a good one. In addition to that here is one another solution that works in O(n) time.
We need to keep track of the previous node in this approach. In each recursive call we check the previous node data with the current node data. If current node data is less than previous we return false
int isBST(node* root) {
static node* prev = NULL;
if(root==NULL)
return 1;
if(!isBST(root->left))
return 0;
if(prev!=NULL && root->data<=prev->data)
return 0;
prev = root;
return isBST(root->right);
}
boolean b = new Sample().isBinarySearchTree(n1, Integer.MIN_VALUE, Integer.MAX_VALUE);
.......
.......
.......
public boolean isBinarySearchTree(TreeNode node, int min, int max){
if(node == null){
return true;
}
boolean left = isBinarySearchTree(node.getLeft(), min, node.getValue());
boolean right = isBinarySearchTree(node.getRight(), node.getValue(), max);
return left && right && (node.getValue()<max) && (node.getValue()>=min);
}
Comments are invited. Thanks.
I think that the second approach is right. The tree can be traversed in a recursive manner. On each iteration lower and upper bounds of current subtree can be stored. If we want to check subtree with root x, and bounds for the subtree are l and h, then all we need is to check that l <= x <= h and to check the left subtree with bounds l and x, and the right one with bounds x and h.
This will have O(n) complexity, because we start from the root and each node is checked only once as root of some subtree. Also, we need O(h) memory for recursive calls, where h is the height of the tree.
There are some examples above using INTEGER.MAX AND MIN
I cant see a reason to pass them and the significance of it,
correct me if I am wrong in anyway or explain me the reason.
More over binary search tree may have objects which are compared by compareTo method or Coperator.. ( hence Integer.MIN and Integer.MAX dont fit on that model)
I am writing a code where it returns true or false
one has to call (root_node,true) and it will return true if it is a bst else false
void boolean isBSt( node root_node, boolean passed_root)
{
if ( node==null){
if ( passed_root)
return false;
// you have passed null pointer as
//root of the tree , since there is no
// valid start point we can throw an exception or return false
return true;
}
if( node.right !=null )
if ( node.right.data <= node.data)
return false;
if ( node.left !=null )
if ! ( node.left.data <= node.data)
return false;
return ( isBST( node.right , false) && isBST( node.left, false ) )
}
Have a look at this solution:
http://preparefortechinterview.blogspot.com/2013/09/am-i-bst.html
It explains different ways and gives you a generic and efficient method too. Hope it helps.
Here is another Solution which uses 2 helper functions to calculate for each node the min and max value in the subtree using the helper function minValue and maxValue
int isBST(struct node* node)
{
if (node == NULL)
return(true);
/* false if the max of the left is > than us */
if (node->left!=NULL && maxValue(node->left) > node->data)
return(false);
/* false if the min of the right is <= than us */
if (node->right!=NULL && minValue(node->right) < node->data)
return(false);
/* false if, recursively, the left or right is not a BST */
if (!isBST(node->left) || !isBST(node->right))
return(false);
/* passing all that, it's a BST */
return(true);
}

Resources