# Split a BST into two balanced BSTs based on a value K

• Difficulty Level : Hard
• Last Updated : 04 Jan, 2023

Given a Binary Search tree and an integer K, we have to split the tree into two Balanced Binary Search Tree, where BST-1 consists of all the nodes which are less than K and BST-2 consists of all the nodes which are greater than or equal to K.
Note: The arrangement of the nodes may be anything but both BST should be Balanced.

Examples:

Input:
40
/   \
20     50
/  \      \
10   35     60
/      /
25      55
K = 35
Output:
First BST: 10 20 25
Second BST: 35 40 50 55 60
Explanation:
After splitting above BST
about given value K = 35
First Balanced Binary Search Tree is
20
/   \
10     25
Second Balanced Binary Search Tree is
50
/   \
35     55
\      \
40     60
OR
40
/   \
35     55
/   \
50    60

Input:
100
/   \
20     500
/  \
10   30
\
40
K = 50
Output:
First BST: 10 20 30 40
Second BST: 100 500
Explanation:
After splitting above BST
about given value K = 50
First Balanced Binary Search Tree is
20
/   \
10     30
\
40
Second Balanced Binary Search Tree is
100
\
500

Approach:

Below is the implementation of the above approach:

## C++

 // C++ program to split a BST into// two balanced BSTs based on a value K #include using namespace std; // Structure of each node of BSTstruct node {    int key;    struct node *left, *right;}; // A utility function to// create a new BST nodenode* newNode(int item){    node* temp = new node();    temp->key = item;    temp->left = temp->right = NULL;    return temp;} // A utility function to insert a new// node with given key in BSTstruct node* insert(struct node* node,                    int key){    // If the tree is empty, return a new node    if (node == NULL)        return newNode(key);     // Otherwise, recur down the tree    if (key < node->key)        node->left = insert(node->left,                            key);    else if (key > node->key)        node->right = insert(node->right,                             key);     // return the (unchanged) node pointer    return node;} // Function to return the size// of the treeint sizeOfTree(node* root){    if (root == NULL) {        return 0;    }     // Calculate left size recursively    int left = sizeOfTree(root->left);     // Calculate right size recursively    int right = sizeOfTree(root->right);     // Return total size recursively    return (left + right + 1);} // Function to store inorder// traversal of BSTvoid storeInorder(node* root,                  int inOrder[],                  int& index){    // Base condition    if (root == NULL) {        return;    }     // Left recursive call    storeInorder(root->left,                 inOrder, index);     // Store elements in inorder array    inOrder[index++] = root->key;     // Right recursive call    storeInorder(root->right,                 inOrder, index);} // Function to return the splitting// index of the arrayint getSplittingIndex(int inOrder[],                      int index, int k){    for (int i = 0; i < index; i++) {        if (inOrder[i] >= k) {            return i - 1;        }    }    return index - 1;} // Function to create the Balanced// Binary search treenode* createBST(int inOrder[],                int start, int end){    // Base Condition    if (start > end) {        return NULL;    }     // Calculate the mid of the array    int mid = (start + end) / 2;    node* t = newNode(inOrder[mid]);     // Recursive call for left child    t->left = createBST(inOrder,                        start, mid - 1);     // Recursive call for right child    t->right = createBST(inOrder,                         mid + 1, end);     // Return newly created Balanced    // Binary Search Tree    return t;} // Function to traverse the tree// in inorder fashionvoid inorderTrav(node* root){    if (root == NULL)        return;    inorderTrav(root->left);    cout << root->key << " ";    inorderTrav(root->right);} // Function to split the BST// into two Balanced BSTvoid splitBST(node* root, int k){     // Print the original BST    cout << "Original BST : ";    if (root != NULL) {        inorderTrav(root);    }    else {        cout << "NULL";    }    cout << endl;     // Store the size of BST1    int numNode = sizeOfTree(root);     // Take auxiliary array for storing    // The inorder traversal of BST1    int inOrder[numNode + 1];    int index = 0;     // Function call for storing    // inorder traversal of BST1    storeInorder(root, inOrder, index);     // Function call for getting    // splitting index    int splitIndex        = getSplittingIndex(inOrder,                            index, k);     node* root1 = NULL;    node* root2 = NULL;     // Creation of first Balanced    // Binary Search Tree    if (splitIndex != -1)        root1 = createBST(inOrder, 0,                          splitIndex);     // Creation of Second Balanced    // Binary Search Tree    if (splitIndex != (index - 1))        root2 = createBST(inOrder,                          splitIndex + 1,                          index - 1);     // Print two Balanced BSTs    cout << "First BST : ";    if (root1 != NULL) {        inorderTrav(root1);    }    else {        cout << "NULL";    }    cout << endl;     cout << "Second BST : ";    if (root2 != NULL) {        inorderTrav(root2);    }    else {        cout << "NULL";    }} // Driver codeint main(){    /*  BST             5           /   \               3     7             / \   / \            2  4  6  8     */    struct node* root = NULL;    root = insert(root, 5);    insert(root, 3);    insert(root, 2);    insert(root, 4);    insert(root, 7);    insert(root, 6);    insert(root, 8);     int k = 5;     // Function to split BST    splitBST(root, k);     return 0;}

## Java

 // Java program to split a BST into// two balanced BSTs based on a value Kimport java.util.*; class GFG{   // Structure of each node of BST  static class node {    int key;    node left, right;  };  static int index;     // A utility function to  // create a new BST node  static node newNode(int item)  {    node temp = new node();    temp.key = item;    temp.left = temp.right = null;    return temp;  }   // A utility function to insert a new  // node with given key in BST  static node insert(node node,                     int key)  {         // If the tree is empty, return a new node    if (node == null)      return newNode(key);     // Otherwise, recur down the tree    if (key < node.key)      node.left = insert(node.left,                         key);    else if (key > node.key)      node.right = insert(node.right,                          key);     // return the (unchanged) node pointer    return node;  }   // Function to return the size  // of the tree  static int sizeOfTree(node root)  {    if (root == null) {      return 0;    }     // Calculate left size recursively    int left = sizeOfTree(root.left);     // Calculate right size recursively    int right = sizeOfTree(root.right);     // Return total size recursively    return (left + right + 1);  }   // Function to store inorder  // traversal of BST  static void storeInorder(node root,                           int inOrder[])  {         // Base condition    if (root == null) {      return;    }     // Left recursive call    storeInorder(root.left,                 inOrder);     // Store elements in inorder array    inOrder[index++] = root.key;     // Right recursive call    storeInorder(root.right,                 inOrder);  }   // Function to return the splitting  // index of the array  static int getSplittingIndex(int inOrder[],                               int k)  {    for (int i = 0; i < index; i++) {      if (inOrder[i] >= k) {        return i - 1;      }    }    return index - 1;  }   // Function to create the Balanced  // Binary search tree  static node createBST(int inOrder[],                        int start, int end)  {    // Base Condition    if (start > end) {      return null;    }     // Calculate the mid of the array    int mid = (start + end) / 2;    node t = newNode(inOrder[mid]);     // Recursive call for left child    t.left = createBST(inOrder,                       start, mid - 1);     // Recursive call for right child    t.right = createBST(inOrder,                        mid + 1, end);     // Return newly created Balanced    // Binary Search Tree    return t;  }   // Function to traverse the tree  // in inorder fashion  static void inorderTrav(node root)  {    if (root == null)      return;    inorderTrav(root.left);    System.out.print(root.key+ " ");    inorderTrav(root.right);  }   // Function to split the BST  // into two Balanced BST  static void splitBST(node root, int k)  {     // Print the original BST    System.out.print("Original BST : ");    if (root != null) {      inorderTrav(root);    }    else {      System.out.print("null");    }    System.out.println();     // Store the size of BST1    int numNode = sizeOfTree(root);     // Take auxiliary array for storing    // The inorder traversal of BST1    int []inOrder = new int[numNode + 1];    index = 0;     // Function call for storing    // inorder traversal of BST1    storeInorder(root, inOrder);     // Function call for getting    // splitting index    int splitIndex      = getSplittingIndex(inOrder,                          k);     node root1 = null;    node root2 = null;     // Creation of first Balanced    // Binary Search Tree    if (splitIndex != -1)      root1 = createBST(inOrder, 0,                        splitIndex);     // Creation of Second Balanced    // Binary Search Tree    if (splitIndex != (index - 1))      root2 = createBST(inOrder,                        splitIndex + 1,                        index - 1);     // Print two Balanced BSTs    System.out.print("First BST : ");    if (root1 != null) {      inorderTrav(root1);    }    else {      System.out.print("null");    }    System.out.println();     System.out.print("Second BST : ");    if (root2 != null) {      inorderTrav(root2);    }    else {      System.out.print("null");    }  }   // Driver code  public static void main(String[] args)  {    /*  BST             5           /   \               3     7             / \   / \            2  4  6  8     */    node root = null;    root = insert(root, 5);    insert(root, 3);    insert(root, 2);    insert(root, 4);    insert(root, 7);    insert(root, 6);    insert(root, 8);     int k = 5;     // Function to split BST    splitBST(root, k);   }} // This code is contributed by Rajput-Ji

## Python3

 # Python 3 program to split a# BST into two balanced BSTs# based on a value Kindex = 0 # Structure of each node of BSTclass newNode:    def __init__(self, item):               # A utility function to        # create a new BST node        self.key = item        self.left = None        self.right = None # A utility function to insert# a new node with given key# in BSTdef insert(node, key):       # If the tree is empty,    # return a new node    if (node == None):        return newNode(key)     # Otherwise, recur down    # the tree    if (key < node.key):        node.left = insert(node.left,                           key)    elif (key > node.key):        node.right = insert(node.right,                            key)     # return the (unchanged)    # node pointer    return node # Function to return the# size of the treedef sizeOfTree(root):       if (root == None):        return 0     # Calculate left size    # recursively    left = sizeOfTree(root.left)     # Calculate right size    # recursively    right = sizeOfTree(root.right)     # Return total size    # recursively    return (left + right + 1) # Function to store inorder# traversal of BSTdef storeInorder(root, inOrder):       global index    # Base condition    if (root == None):        return     # Left recursive call    storeInorder(root.left,                 inOrder)     # Store elements in    # inorder array    inOrder[index] = root.key    index += 1     # Right recursive call    storeInorder(root.right,                 inOrder) # Function to return the# splitting index of the# arraydef getSplittingIndex(inOrder,                      index, k):       for i in range(index):        if (inOrder[i] >= k):            return i - 1    return index - 1 # Function to create the# Balanced Binary search# treedef createBST(inOrder,              start, end):       # Base Condition    if (start > end):        return None     # Calculate the mid of    # the array    mid = (start + end) // 2    t = newNode(inOrder[mid])     # Recursive call for    # left child    t.left = createBST(inOrder,                       start,                       mid - 1)     # Recursive call for    # right child    t.right = createBST(inOrder,                        mid + 1, end)     # Return newly created    # Balanced Binary Search    # Tree    return t # Function to traverse# the tree in inorder# fashiondef inorderTrav(root):       if (root == None):        return           inorderTrav(root.left)    print(root.key, end = " ")    inorderTrav(root.right) # Function to split the BST# into two Balanced BSTdef splitBST(root, k):       global index         # Print the original BST    print("Original BST : ")    if (root != None):        inorderTrav(root)        print("\n", end = "")    else:        print("NULL")     # Store the size of BST1    numNode = sizeOfTree(root)     # Take auxiliary array for    # storing The inorder traversal    # of BST1    inOrder = [0 for i in range(numNode + 1)]    index = 0     # Function call for storing    # inorder traversal of BST1    storeInorder(root, inOrder)     # Function call for getting    # splitting index    splitIndex = getSplittingIndex(inOrder,                                   index, k)     root1 = None    root2 = None     # Creation of first Balanced    # Binary Search Tree    if (splitIndex != -1):        root1 = createBST(inOrder,                          0, splitIndex)     # Creation of Second Balanced    # Binary Search Tree    if (splitIndex != (index - 1)):        root2 = createBST(inOrder,                          splitIndex + 1,                          index - 1)     # Print two Balanced BSTs    print("First BST : ")    if (root1 != None):        inorderTrav(root1)        print("\n", end = "")    else:        print("NULL")     print("Second BST : ")    if (root2 != None):        inorderTrav(root2)        print("\n", end = "")    else:        print("NULL") # Driver codeif __name__ == '__main__':       '''/*  BST             5           /   /               3     7             / /   / /            2  4  6  8     */'''    root = None    root = insert(root, 5)    insert(root, 3)    insert(root, 2)    insert(root, 4)    insert(root, 7)    insert(root, 6)    insert(root, 8)     k = 5     # Function to split BST    splitBST(root, k) # This code is contributed by Chitranayal

## C#

 // C# program to split a BST into// two balanced BSTs based on a value Kusing System; public class GFG{   // Structure of each node of BST  public class node {    public int key;    public node left, right;  };  static int index;   // A utility function to  // create a new BST node  static node newNode(int item)  {    node temp = new node();    temp.key = item;    temp.left = temp.right = null;    return temp;  }   // A utility function to insert a new  // node with given key in BST  static node insert(node node,                     int key)  {     // If the tree is empty, return a new node    if (node == null)      return newNode(key);     // Otherwise, recur down the tree    if (key < node.key)      node.left = insert(node.left,                         key);    else if (key > node.key)      node.right = insert(node.right,                          key);     // return the (unchanged) node pointer    return node;  }   // Function to return the size  // of the tree  static int sizeOfTree(node root)  {    if (root == null) {      return 0;    }     // Calculate left size recursively    int left = sizeOfTree(root.left);     // Calculate right size recursively    int right = sizeOfTree(root.right);     // Return total size recursively    return (left + right + 1);  }   // Function to store inorder  // traversal of BST  static void storeInorder(node root,                           int []inOrder)  {     // Base condition    if (root == null) {      return;    }     // Left recursive call    storeInorder(root.left,                 inOrder);     // Store elements in inorder array    inOrder[index++] = root.key;     // Right recursive call    storeInorder(root.right,                 inOrder);  }   // Function to return the splitting  // index of the array  static int getSplittingIndex(int []inOrder,                               int k)  {    for (int i = 0; i < index; i++) {      if (inOrder[i] >= k) {        return i - 1;      }    }    return index - 1;  }   // Function to create the Balanced  // Binary search tree  static node createBST(int []inOrder,                        int start, int end)  {    // Base Condition    if (start > end) {      return null;    }     // Calculate the mid of the array    int mid = (start + end) / 2;    node t = newNode(inOrder[mid]);     // Recursive call for left child    t.left = createBST(inOrder,                       start, mid - 1);     // Recursive call for right child    t.right = createBST(inOrder,                        mid + 1, end);     // Return newly created Balanced    // Binary Search Tree    return t;  }   // Function to traverse the tree  // in inorder fashion  static void inorderTrav(node root)  {    if (root == null)      return;    inorderTrav(root.left);    Console.Write(root.key+ " ");    inorderTrav(root.right);  }   // Function to split the BST  // into two Balanced BST  static void splitBST(node root, int k)  {     // Print the original BST    Console.Write("Original BST : ");    if (root != null) {      inorderTrav(root);    }    else {      Console.Write("null");    }    Console.WriteLine();     // Store the size of BST1    int numNode = sizeOfTree(root);     // Take auxiliary array for storing    // The inorder traversal of BST1    int []inOrder = new int[numNode + 1];    index = 0;     // Function call for storing    // inorder traversal of BST1    storeInorder(root, inOrder);     // Function call for getting    // splitting index    int splitIndex      = getSplittingIndex(inOrder,                          k);     node root1 = null;    node root2 = null;     // Creation of first Balanced    // Binary Search Tree    if (splitIndex != -1)      root1 = createBST(inOrder, 0,                        splitIndex);     // Creation of Second Balanced    // Binary Search Tree    if (splitIndex != (index - 1))      root2 = createBST(inOrder,                        splitIndex + 1,                        index - 1);     // Print two Balanced BSTs    Console.Write("First BST : ");    if (root1 != null) {      inorderTrav(root1);    }    else {      Console.Write("null");    }    Console.WriteLine();     Console.Write("Second BST : ");    if (root2 != null) {      inorderTrav(root2);    }    else {      Console.Write("null");    }  }   // Driver code  public static void Main(String[] args)  {    /*  BST             5           /   \               3     7             / \   / \            2  4  6  8     */    node root = null;    root = insert(root, 5);    insert(root, 3);    insert(root, 2);    insert(root, 4);    insert(root, 7);    insert(root, 6);    insert(root, 8);     int k = 5;     // Function to split BST    splitBST(root, k);   }} // This code is contributed by Rajput-Ji

## Javascript



Output:

Original BST : 2 3 4 5 6 7 8
First BST : 2 3 4
Second BST : 5 6 7 8

Time Complexity: where n is the number of nodes in the BST. This is because the function storeInorder() traverses through all the nodes of the BST inorder and the function createBST() traverses through all the nodes of the balanced BST that it creates.
Auxiliary Space: where n is the number of nodes in the BST. This is because an array of size n is created to store the inorder traversal of the BST. Additionally, a new balanced BST is created from the inorder traversal, which also requires space.

My Personal Notes arrow_drop_up