Given a Binary Tree, write code to convert it to Binary Search Tree such that the structure of the tree remains the same. For example: Both the below trees

          5                        10
        /   \                    /    \
       8    10                  5     30
     /  \     \               /   \     \
    4   30     1             8    40     1
   /                        /
  40                       4

Should generate the below Binary Search Tree.

Note that the structure of the tree remains the same. Hence all the three trees above are Similar.

Solution:

For this we need an extra array of size n (Number of Nodes) to store the inorder traversal of the tree.

Algorithm:

1. Traverse the tree in inorder and store the values in array.
2. Sort the Array.
3. Traverse the tree again in in-order and copy the values from array in the Nodes.

Code:

/**
 * Populate the array arr with the inorder traversal of the tree pointed to by r.
 * pos holds a reference to the current poisition of arr.
 */
void populateInorderArray(Node*  r, int* arr, int* pos)
{
    if(r == NULL)
        return;
    populateInorderArray(r->lptr, arr, pos);
    arr[*pos] = r->data;
    (*pos)++;
    populateInorderArray(r->rptr, arr, pos);
}
/**
 * Traverse the Tree in Inorder traversal and copy the values from
 * array arr to the nodes of the tree.
 *
 * pos holds a reference to the current poisition of arr.
 */
void copyInorderArrayToTree(Node* r, int* arr, int* pos)
{
    if(r == NULL)
        return;
    copyInorderArrayToTree(r->lptr, arr, pos);
    r->data = arr[*pos];
    (*pos)++;
    copyInorderArrayToTree(r->rptr, arr, pos);
}
/** Functions accepts a pointer to the root of a Binary Tree
 * and converts it to Binary Search Tree.
 * We don't need a Node**, because we are not changing the root node,
 * We are only changing the value contained in the root node.
 *
 * Structure of the tree remains the same.
 */
void converttoBST(Node* r)
{
    if(NULL == r)
        return;
    // hard-codding it to 1000 for simplicity.
    // define the array equal to number of nodes.
    int arr[1000] = {0};
    int n = 0;    // Will hold the number of Nodes
    populateInorderArray(r, arr, &n);
    quickSort(arr, 0, n-1);
    n=0;
    copyInorderArrayToTree(r, arr, &n);
}

I am sure you can write the Quick Sort algorithm. Ok, let me write the function to sort the array also (as used in the above code).

/** Helper function to partition the array for a pivot.
 */
int partition(int *arr, int low, int high)
{
    int p = low;
    low++;
    while(low<=high)
    {
        while(arr[low]<arr[p]) low++;
        while(arr[high]>arr[p]) high--;
        if(low<high)
        {
            int temp = arr[low];
            arr[low] = arr[high];
            arr[high] = temp;
        }
    }
    int temp = arr[p];
    arr[p] = arr[high];
    arr[high] = temp;
    return high;
}
/** Function to sort the array using Quick sort algorithm
 */
void quickSort(int* arr, int a, int b)
{
    if(a>=b)
        return;
    int pos = partition(arr, a, b);
    quickSort(arr, a, pos-1);
    quickSort(arr, pos+1, b);
}

Time Complexity:

Time to populate Inorder Array = O(n)
Time to Sort Inorder Array = O(n.lg(n))
Time to Put values from Sorter array to Tree = O(n)
Total Time = O(n) + O(n.lg(n)) + O(n) = O(n.lg(n))

Note: The above implementation of Quick sort takes O(n2) time in worst case, because we are not choosing the pivot randomly. But a randomized Quick Sort algorithm takes O(n.lg(n)) time in the worst case.
Extra Space Used: O(n)
Note: The array uses extra space O(n). even if we do not use the array, the Inorder algorithm takes O(n) space because of Recursion.

One Response

  1. hi this is my function which converts the sorted array to BST
    public static void BTtoBSTUtil2(Node root,ArrayListarr,int i) {
    System.out.println(“i1″+i);
    if(root!=null) {
    BTtoBSTUtil2(root.left, arr,i);
    // System.out.println(“i1″+i);
    root.data=arr.get(i);
    i++;
    //System.out.println(“i2″+i);
    BTtoBSTUtil2(root.right, arr,i);
    }
    }
    Its not working. Please help me out

Leave a Reply

Your email address will not be published. Required fields are marked *