GeeksforGeeks » Trees specific questions

Binary Tree to BST

(15 posts)
  • Started 2 years ago by deepak
  • Latest reply from varadharajan

Tags:

  1. deepak
    guest
    Posted 2 years ago #

    convert a binary tree to binary search tree inplace. We cant use any extra space.

  2. geek4u
    guest
    Posted 2 years ago #

    If array representation of tree is used then problem reduces to just sorting the array. You can use any in-place sorting algorithm like bubble sort, quick sort, .. etc

  3. Shekhu
    guest
    Posted 2 years ago #

    Simply sorting the array won't work. Inorder of a BST is sorted, not level order.

    Here is one approach that works for both array and LL implementations.

    TreeToBST(root)
    1) If tree is empty then return.
    2) Call TreeToBST for left subtree, i.e., TreeToBST(root->left)
    3) Call TreeToBST for right subtree, i,e., TreeToBST(root->right)
    4) Fix the current node, i.e., root
              a) Get middle, max and min of data at  root, root->left and root->right
              b) Put mid value at root, min at root->left and max at root->right
    
  4. geek4u
    guest
    Posted 2 years ago #

    Can you write C implementation? Thanks.

  5. Shekhu
    guest
    Posted 2 years ago #

    My bad :( I tried to code it and realized that the approach doesn't work for many trees.

    For example, in case of below tree.

             7
          /    \
        6       3
                   \
                    5
    

    The output of above algo is

             6
          /    \
        3        7
                      \
                       5
    

    which is incorrect :((

  6. Shekhu
    guest
    Posted 2 years ago #

    Another simple O(nLogn) solution.
    1) Do Inorder traversal of the tree and read the result in an array.
    2) Sort the array.
    3) Again do Inorder traversal and write the node's data one by one from array.

    But, extra O(n) space is used here.

  7. vramanan
    guest
    Posted 1 year ago #

    strut info {
        struct node *min;
        struct node *max;
        struct node *root;
    } info*;
    
    struct info* convertToBST(struct node *T) {
          struct info* ret;
          if (!T) {
              return NULL;
          }
    
         ret->min = T;
         ret->max = T;
         ret->root = T;
    
         if (!T->left && !T->right) {
             return ret;
         }
    
         struct *info linfo = convertToBST(T->left);
         struct *info rinfo = convertToBST(T->right);
    
         if (linfo) {
              if (T->data < linfo->min->data) {
                   swap(T->data, linfo->min->data);
              }
              ret->min = linfo->min->data;
         }
         if (rinfo) {
              if (T->data > rinfo->max->data) {
                   swap(T->data, rinfo->max->data);
              }
             ret->max = rinfo->max->data;
         }
         return ret;
    }
    
    driverFunc(T) {
        struct info *ret;
    
        ret = convertToBST(T);
    
         printTree(ret->root);
    }
    
  8. abc
    guest
    Posted 1 year ago #

    I guess there is something wrong in the code.
    How can we have:
    ret->min = linfo->min->data;
    and
    ret->max = rinfo->max->data;

  9. carstenh
    Member
    Posted 1 year ago #

    Here is one way of doing it.

    We have a function

    Node* CreateBST(Node* root);

    that we are going to call recursively. It is trivial to get it to work if the number of nodes, n, in the binary tree is less than or equal to 1.
    Now assume that n > 1 and the function works for all values strictly less than n.

    We can call CreateBST on root->left_child and root->right_child to make both subtrees BSTs.

    Assume the left subtree has k nodes.
    We now do an inorder traversal of the two subtrees to find the (k+1)th node wrt the ordering comparing what is in the left subtree, what is in the right subtree and what is in the root.
    Interchange the data with the data pointing to by the root.
    We now have the right root.

    Now do another inorder traversal of the two subtrees interchanging data in the left subtree which are greater than the data pointing to by the root with data in the right subtree which are less than the data pointing to by the root.
    Because we have the right data at the root the numbers of such data in the two subtrees are identical.

    Finally we again call CreateBST on root->left_child and root->right_child and we are done.

  10. manishj
    Member
    Posted 1 year ago #

    This algorithm is based on max-heapify.

    
    btree* max_tree(btree *root)
    {
    	if(root == NULL)
    		return root;
    	btree * current = root;
    	while(current->right != NULL)
    	{
    		current = current->right;
    	}
    	return current;
    }
    btree * min_tree(btree *root)
    {
    	if(root == NULL)
    		return root;
    	btree * current = root;
    	while(current->left != NULL)
    	{
    		current = current->left;
    	}
    	return current;
    }
    void binarytreetobst(btree *root)
    {
    //base-case tree is empty
    	if(root == NULL)
    		return;
    	else if(root->left == NULL && root->right == NULL) //base-case tree of size 1
    		return;
    	else
    	{
    		binarytreetobst(root->left);
    		binarytreetobst(root->right);
    
    		btree* max = max_tree(root->left);
    		if(max && max->data > root->data)
    		{
    			int temp = root->data;
    			root->data = max->data;
    			max->data = temp;
    			binarytreetobst(root->left);
    
    		}
    		btree* min = min_tree(root->right);
    		if(min && min->data  < root->data)
    		{
    			int temp = root->data;
    			root->data = min->data;
    			min->data = temp;
    			binarytreetobst(root->right);
    		}
    	}
    }
    
  11. Isaac
    guest
    Posted 1 year ago #

    import java.util.Comparator;
    
    public class TraversalAlgorithms {
    
    	public static BinaryTree<Integer> finMax(BinaryTree<Integer> tree) {
    		return morrisFind(tree, new Comparator<Integer>() {
    			public int compare(Integer o1, Integer o2) {
    				return o1.compareTo(o2);
    			}
    		});
    	}
    
    	public static BinaryTree<Integer> finMin(BinaryTree<Integer> tree) {
    		return morrisFind(tree, new Comparator<Integer>() {
    			public int compare(Integer o1, Integer o2) {
    				return -1 * o1.compareTo(o2);
    			}
    		});
    	}
    
    	public static BinaryTree<Integer> morrisFind(BinaryTree<Integer> root,
                                                                         Comparator<Integer> comparator)
           {
    		BinaryTree<Integer> current = root;
    		int result = current.getRoot();
    		BinaryTree<Integer> resultTree = current;
    		while (current != null) {
    			if (current.getLeft() == null) {
    				if (comparator.compare(current.getRoot(), result) > 0) {
    					result = current.getRoot();
    					resultTree = current;
    				}
    				current = current.getRight();
    			} else {
    				BinaryTree<Integer> pre = current.getLeft();
    				while (pre.getRight() != null && pre.getRight() != current) {
    					pre = pre.getRight();
    				}
    				if (pre.getRight() == null) {
    					pre.setRight(current);
    					current = current.getLeft();
    				} else {
    					pre.setRight(null);
    					if (comparator.compare(current.getRoot(), result) > 0) {
    						result = current.getRoot();
    						resultTree = current;
    					}
    					current = current.getRight();
    				}
    			}
    		}
    		return resultTree;
    	}
    }
    
    public class ManipluationAlgorithms {
    	public static void bt2bst(BinaryTree<Integer> tree) {
    		if (tree != null) {
    			BinaryTree<Integer> currTree = tree;
    			int root = tree.getRoot();
    			BinaryTree<Integer> maxLeftTree = null;
    			BinaryTree<Integer> minRightTree = null;
    			if (currTree.getLeft() != null) {
    				maxLeftTree = TraversalAlgorithms.finMax(currTree.getLeft());
    			}
    
    			if (currTree.getRight() != null) {
    				minRightTree = TraversalAlgorithms.finMin(currTree.getRight());
    			}
    
    			if (maxLeftTree != null && minRightTree != null &&
                                maxLeftTree.getRoot() > minRightTree.getRoot()) {
    				swapRoots(maxLeftTree, minRightTree);
    				bt2bst(currTree);
    			} else if (maxLeftTree != null && maxLeftTree.getRoot() > root) {
    				swapRoots(maxLeftTree, currTree);
    				bt2bst(currTree);
    			} else if (minRightTree != null && minRightTree.getRoot() < root) {
    				swapRoots(minRightTree, currTree);
    				bt2bst(currTree);
    			} else {
    				if (currTree.getLeft() != null) {
    					bt2bst(currTree.getLeft());
    				}
    				if (currTree.getRight() != null) {
    					bt2bst(currTree.getRight());
    				}
    			}
    		}
    	}
    
    	private static void swapRoots(BinaryTree<Integer> tree1,
                                                                 BinaryTree<Integer> tree2)
            {
    		int tmp = tree1.getRoot();
    		tree1.setRoot(tree2.getRoot());
    		tree2.setRoot(tmp);
    	}
    
    	public static void main(String[] args) {
    		BinaryTree<Integer> ll2 =
                                     new BinaryTree<Integer>(14, new BinaryTree<Integer>(1),
    				 new BinaryTree<Integer>(12));
    		BinaryTree<Integer> lr2 =
                                     new BinaryTree<Integer>(3, new BinaryTree<Integer>(10),
    				 new BinaryTree<Integer>(5));
    		BinaryTree<Integer> rl2 =
                                     new BinaryTree<Integer>(8, new BinaryTree<Integer>(7),
    				 new BinaryTree<Integer>(6));
    		BinaryTree<Integer> rr2 =
                                      new BinaryTree<Integer>(9, new BinaryTree<Integer>(4),
    				  new BinaryTree<Integer>(11));
    		BinaryTree<Integer> l2 = new BinaryTree<Integer>(2, ll2, lr2);
    		BinaryTree<Integer> r2 = new BinaryTree<Integer>(13, rl2, rr2);
    		BinaryTree<Integer> bt = new BinaryTree<Integer>(15, l2, r2);
    		bt2bst(bt);
    	}
    }
    
  12. Isaac
    guest
    Posted 1 year ago #

    this is binary tree class

    public class BinaryTree<T> {
    	private T root;
    	private BinaryTree<T> left;
    	private BinaryTree<T> right;
    
    	public BinaryTree(T root, BinaryTree<T> left, BinaryTree<T> right) {
    		this.root = root;
    		this.left = left;
    		this.right = right;
    	}
    
    	public BinaryTree(T root) {
    		this.root = root;
    		this.left = null;
    		this.right = null;
    	}
    
    	public BinaryTree<T> getLeft() {
    		return left;
    	}
    
    	public BinaryTree<T> getRight() {
    		return right;
    	}
    
    	public void setRight(BinaryTree<T> right) {
    		this.right = right;
    	}
    
    	public T getRoot() {
    		return root;
    	}
    
    	@Override
    	public String toString() {
    		return getRoot() + "(" + ((getLeft() != null) ? getLeft().getRoot() : null) + ") ("
    				+ ((getRight() != null) ? getRight().getRoot() : null)
    				+ ")";
    	}
    
    	public void setRoot(T newRoot) {
    		this.root = newRoot;
    	}
    }
    
  13. faint
    guest
    Posted 1 year ago #

    no one says structure of tree need to be preserved, so just create a new tree and add node one by one from old tree.
    http://stackoverflow.com/questions/2848067/binary-tree-to-bst

  14. Abhi
    guest
    Posted 4 months ago #

    @manishj

    nice algo........................what is the complexity????

  15. varadharajan
    Member
    Posted 3 days ago #

    @manishj Thanks for posting...


Reply

You must log in to post.

RSS feed for this topic