Given a Singly Linked List which has data members sorted in ascending order. Construct a Balanced Binary Search Tree which has same data members as the given Linked List.
Examples:
Input: Linked List 1->2->3
Output: A Balanced BST
2
/ \
1 3
Input: Linked List 1->2->3->4->5->6->7
Output: A Balanced BST
4
/ \
2 6
/ \ / \
1 3 5 7
Input: Linked List 1->2->3->4
Output: A Balanced BST
3
/ \
2 4
/
1
Input: Linked List 1->2->3->4->5->6
Output: A Balanced BST
4
/ \
2 6
/ \ /
1 3 5
Method 1 (Simple)
Following is a simple algorithm where we first find the middle node of the list and make it the root of the tree to be constructed.
1) Get the Middle of the linked list and make it root.
2) Recursively do same for the left half and right half.
a) Get the middle of the left half and make it left child of the root
created in step 1.
b) Get the middle of right half and make it the right child of the
root created in step 1.
Time complexity: O(nLogn) where n is the number of nodes in Linked List.
Method 2 (Tricky)
Method 1 constructs the tree from root to leaves. In this method, we construct from leaves to root. The idea is to insert nodes in BST in the same order as they appear in Linked List so that the tree can be constructed in O(n) time complexity. We first count the number of nodes in the given Linked List. Let the count be n. After counting nodes, we take left n/2 nodes and recursively construct the left subtree. After left subtree is constructed, we allocate memory for root and link the left subtree with root. Finally, we recursively construct the right subtree and link it with root.
While constructing the BST, we also keep moving the list head pointer to next so that we have the appropriate pointer in each recursive call.
Following is implementation of method 2. The main code which creates Balanced BST is highlighted.
C++
#include <bits/stdc++.h>
using namespace std;
class LNode
{
public :
int data;
LNode* next;
};
class TNode
{
public :
int data;
TNode* left;
TNode* right;
};
TNode* newNode( int data);
int countLNodes(LNode *head);
TNode* sortedListToBSTRecur(LNode **head_ref, int n);
TNode* sortedListToBST(LNode *head)
{
int n = countLNodes(head);
return sortedListToBSTRecur(&head, n);
}
TNode* sortedListToBSTRecur(LNode **head_ref, int n)
{
if (n <= 0)
return NULL;
TNode *left = sortedListToBSTRecur(head_ref, n/2);
TNode *root = newNode((*head_ref)->data);
root->left = left;
*head_ref = (*head_ref)->next;
root->right = sortedListToBSTRecur(head_ref, n - n / 2 - 1);
return root;
}
int countLNodes(LNode *head)
{
int count = 0;
LNode *temp = head;
while (temp)
{
temp = temp->next;
count++;
}
return count;
}
void push(LNode** head_ref, int new_data)
{
LNode* new_node = new LNode();
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
void printList(LNode *node)
{
while (node!=NULL)
{
cout << node->data << " " ;
node = node->next;
}
}
TNode* newNode( int data)
{
TNode* node = new TNode();
node->data = data;
node->left = NULL;
node->right = NULL;
return node;
}
void preOrder(TNode* node)
{
if (node == NULL)
return ;
cout<<node->data<< " " ;
preOrder(node->left);
preOrder(node->right);
}
int main()
{
LNode* head = NULL;
push(&head, 7);
push(&head, 6);
push(&head, 5);
push(&head, 4);
push(&head, 3);
push(&head, 2);
push(&head, 1);
cout<< "Given Linked List " ;
printList(head);
TNode *root = sortedListToBST(head);
cout<< "\nPreOrder Traversal of constructed BST " ;
preOrder(root);
return 0;
}
|
C
#include<stdio.h>
#include<stdlib.h>
struct LNode
{
int data;
struct LNode* next;
};
struct TNode
{
int data;
struct TNode* left;
struct TNode* right;
};
struct TNode* newNode( int data);
int countLNodes( struct LNode *head);
struct TNode* sortedListToBSTRecur( struct LNode **head_ref, int n);
struct TNode* sortedListToBST( struct LNode *head)
{
int n = countLNodes(head);
return sortedListToBSTRecur(&head, n);
}
struct TNode* sortedListToBSTRecur( struct LNode **head_ref, int n)
{
if (n <= 0)
return NULL;
struct TNode *left = sortedListToBSTRecur(head_ref, n/2);
struct TNode *root = newNode((*head_ref)->data);
root->left = left;
*head_ref = (*head_ref)->next;
root->right = sortedListToBSTRecur(head_ref, n-n/2-1);
return root;
}
int countLNodes( struct LNode *head)
{
int count = 0;
struct LNode *temp = head;
while (temp)
{
temp = temp->next;
count++;
}
return count;
}
void push( struct LNode** head_ref, int new_data)
{
struct LNode* new_node =
( struct LNode*) malloc ( sizeof ( struct LNode));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
void printList( struct LNode *node)
{
while (node!=NULL)
{
printf ( "%d " , node->data);
node = node->next;
}
}
struct TNode* newNode( int data)
{
struct TNode* node = ( struct TNode*)
malloc ( sizeof ( struct TNode));
node->data = data;
node->left = NULL;
node->right = NULL;
return node;
}
void preOrder( struct TNode* node)
{
if (node == NULL)
return ;
printf ( "%d " , node->data);
preOrder(node->left);
preOrder(node->right);
}
int main()
{
struct LNode* head = NULL;
push(&head, 7);
push(&head, 6);
push(&head, 5);
push(&head, 4);
push(&head, 3);
push(&head, 2);
push(&head, 1);
printf ( "\n Given Linked List " );
printList(head);
struct TNode *root = sortedListToBST(head);
printf ( "\n PreOrder Traversal of constructed BST " );
preOrder(root);
return 0;
}
|
Java
class LinkedList {
static LNode head;
class LNode
{
int data;
LNode next, prev;
LNode( int d)
{
data = d;
next = prev = null ;
}
}
class TNode
{
int data;
TNode left, right;
TNode( int d)
{
data = d;
left = right = null ;
}
}
TNode sortedListToBST()
{
int n = countNodes(head);
return sortedListToBSTRecur(n);
}
TNode sortedListToBSTRecur( int n)
{
if (n <= 0 )
return null ;
TNode left = sortedListToBSTRecur(n / 2 );
TNode root = new TNode(head.data);
root.left = left;
head = head.next;
root.right = sortedListToBSTRecur(n - n / 2 - 1 );
return root;
}
int countNodes(LNode head)
{
int count = 0 ;
LNode temp = head;
while (temp != null )
{
temp = temp.next;
count++;
}
return count;
}
void push( int new_data)
{
LNode new_node = new LNode(new_data);
new_node.prev = null ;
new_node.next = head;
if (head != null )
head.prev = new_node;
head = new_node;
}
void printList(LNode node)
{
while (node != null )
{
System.out.print(node.data + " " );
node = node.next;
}
}
void preOrder(TNode node)
{
if (node == null )
return ;
System.out.print(node.data + " " );
preOrder(node.left);
preOrder(node.right);
}
public static void main(String[] args) {
LinkedList llist = new LinkedList();
llist.push( 7 );
llist.push( 6 );
llist.push( 5 );
llist.push( 4 );
llist.push( 3 );
llist.push( 2 );
llist.push( 1 );
System.out.println( "Given Linked List " );
llist.printList(head);
TNode root = llist.sortedListToBST();
System.out.println( "" );
System.out.println( "Pre-Order Traversal of constructed BST " );
llist.preOrder(root);
}
}
|
Python3
class LNode :
def __init__( self ):
self .data = None
self . next = None
class TNode :
def __init__( self ):
self .data = None
self .left = None
self .right = None
head = None
def sortedListToBST():
global head
n = countLNodes(head)
return sortedListToBSTRecur(n)
def sortedListToBSTRecur( n) :
global head
if (n < = 0 ) :
return None
left = sortedListToBSTRecur( int (n / 2 ))
root = newNode((head).data)
root.left = left
head = (head). next
root.right = sortedListToBSTRecur( n - int (n / 2 ) - 1 )
return root
def countLNodes(head) :
count = 0
temp = head
while (temp ! = None ):
temp = temp. next
count = count + 1
return count
def push(head, new_data) :
new_node = LNode()
new_node.data = new_data
new_node. next = (head)
(head) = new_node
return head
def printList(node):
while (node ! = None ):
print ( node.data ,end = " " )
node = node. next
def newNode(data) :
node = TNode()
node.data = data
node.left = None
node.right = None
return node
def preOrder( node) :
if (node = = None ) :
return
print (node.data, end = " " )
preOrder(node.left)
preOrder(node.right)
head = None
head = push(head, 7 )
head = push(head, 6 )
head = push(head, 5 )
head = push(head, 4 )
head = push(head, 3 )
head = push(head, 2 )
head = push(head, 1 )
print ( "Given Linked List " )
printList(head)
root = sortedListToBST()
print ( "\nPreOrder Traversal of constructed BST " )
preOrder(root)
|
C#
using System;
public class LinkedList
{
static LNode head;
class LNode
{
public int data;
public LNode next, prev;
public LNode( int d)
{
data = d;
next = prev = null ;
}
}
class TNode
{
public int data;
public TNode left, right;
public TNode( int d)
{
data = d;
left = right = null ;
}
}
TNode sortedListToBST()
{
int n = countNodes(head);
return sortedListToBSTRecur(n);
}
TNode sortedListToBSTRecur( int n)
{
if (n <= 0)
return null ;
TNode left = sortedListToBSTRecur(n / 2);
TNode root = new TNode(head.data);
root.left = left;
head = head.next;
root.right = sortedListToBSTRecur(n - n / 2 - 1);
return root;
}
int countNodes(LNode head)
{
int count = 0;
LNode temp = head;
while (temp != null )
{
temp = temp.next;
count++;
}
return count;
}
void push( int new_data)
{
LNode new_node = new LNode(new_data);
new_node.prev = null ;
new_node.next = head;
if (head != null )
head.prev = new_node;
head = new_node;
}
void printList(LNode node)
{
while (node != null )
{
Console.Write(node.data + " " );
node = node.next;
}
}
void preOrder(TNode node)
{
if (node == null )
return ;
Console.Write(node.data + " " );
preOrder(node.left);
preOrder(node.right);
}
public static void Main(String[] args)
{
LinkedList llist = new LinkedList();
llist.push(7);
llist.push(6);
llist.push(5);
llist.push(4);
llist.push(3);
llist.push(2);
llist.push(1);
Console.WriteLine( "Given Linked List " );
llist.printList(head);
TNode root = llist.sortedListToBST();
Console.WriteLine( "" );
Console.WriteLine( "Pre-Order Traversal of constructed BST " );
llist.preOrder(root);
}
}
|
Javascript
<script>
var head = null ;
class LNode
{
constructor(d)
{
this .data = d;
this .next = null ;
this .prev = null ;
}
}
class TNode
{
constructor(d)
{
this .data = d;
this .left = null ;
this .right = null ;
}
}
function sortedListToBST()
{
var n = countNodes(head);
return sortedListToBSTRecur(n);
}
function sortedListToBSTRecur(n)
{
if (n <= 0)
return null ;
var left = sortedListToBSTRecur(parseInt(n / 2));
var root = new TNode(head.data);
root.left = left;
head = head.next;
root.right = sortedListToBSTRecur(n - parseInt(n / 2) - 1);
return root;
}
function countNodes(head)
{
var count = 0;
var temp = head;
while (temp != null )
{
temp = temp.next;
count++;
}
return count;
}
function push( new_data)
{
var new_node = new LNode(new_data);
new_node.prev = null ;
new_node.next = head;
if (head != null )
head.prev = new_node;
head = new_node;
}
function printList( node)
{
while (node != null )
{
document.write(node.data + " " );
node = node.next;
}
}
function preOrder(node)
{
if (node == null )
return ;
document.write(node.data + " " );
preOrder(node.left);
preOrder(node.right);
}
push(7);
push(6);
push(5);
push(4);
push(3);
push(2);
push(1);
document.write( "Given Linked List " );
printList(head);
var root = sortedListToBST();
document.write( "<br>" );
document.write( "Pre-Order Traversal of constructed BST " );
preOrder(root);
</script>
|
Output:
Given Linked List 1 2 3 4 5 6 7
PreOrder Traversal of constructed BST 4 2 1 3 6 5 7
Time Complexity: O(n)
Auxiliary Space: O(n) for call stack since using recursion
Another Approach(using extra space):
Follow the below steps to solve this problem:
1) Create a array and store all the elements of linked list.
2) Now find the middle element of the linked list and create it root of the tree and call for left array and right array for left and right child.
3) Now recursively repeat above approach until the start becomes greater than end.
4) Now print the preorder traversal of created tree.
Below is the implementation of above approach:
C++
#include<bits/stdc++.h>
using namespace std;
struct LNode{
int data;
LNode* next;
LNode( int data){
this ->data = data;
this ->next = NULL;
}
};
struct TNode{
int data;
TNode* left;
TNode* right;
TNode( int data){
this ->data = data;
this ->left = NULL;
this ->right = NULL;
}
};
void printList(LNode* node){
while (node != NULL){
cout<<node->data<< " " ;
node = node->next;
}
}
void preOrder(TNode* root){
if (root == NULL) return ;
cout<<root->data<< " " ;
preOrder(root->left);
preOrder(root->right);
}
TNode* sortedListToBSTRecur(vector< int >& vec, int start, int end){
if (start > end) return NULL;
int mid = start + (end-start)/2;
if ((end - start)%2 != 0) mid = mid+1;
TNode* root = new TNode(vec[mid]);
root->left = sortedListToBSTRecur(vec, start, mid-1);
root->right = sortedListToBSTRecur(vec, mid+1, end);
return root;
}
TNode* sortedListToBST(LNode* head){
vector< int > vec;
LNode* temp = head;
while (temp != NULL){
vec.push_back(temp->data);
temp = temp->next;
}
return sortedListToBSTRecur(vec, 0, vec.size()-1);
}
int main(){
LNode* head = new LNode(1);
head->next = new LNode(2);
head->next->next = new LNode(3);
head->next->next->next = new LNode(4);
head->next->next->next->next = new LNode(5);
head->next->next->next->next->next = new LNode(6);
head->next->next->next->next->next->next = new LNode(7);
cout<< "Given Linked List: " <<endl;
printList(head);
cout<<endl;
TNode* root = sortedListToBST(head);
cout<< "Peorder Traversal of constructed BST: " <<endl;
preOrder(root);
return 0;
}
|
Java
import java.util.*;
class LNode {
int data;
LNode next;
LNode( int data) {
this .data = data;
this .next = null ;
}
}
class TNode {
int data;
TNode left;
TNode right;
TNode( int data) {
this .data = data;
this .left = null ;
this .right = null ;
}
}
public class Main {
static void printList(LNode node) {
while (node != null ) {
System.out.print(node.data + " " );
node = node.next;
}
}
static void preOrder(TNode root) {
if (root == null ) {
return ;
}
System.out.print(root.data + " " );
preOrder(root.left);
preOrder(root.right);
}
static TNode sortedListToBSTRecur(List<Integer> vec, int start, int end) {
if (start > end) {
return null ;
}
int mid = start + (end - start) / 2 ;
if ((end - start) % 2 != 0 ) {
mid = mid + 1 ;
}
TNode root = new TNode(vec.get(mid));
root.left = sortedListToBSTRecur(vec, start, mid - 1 );
root.right = sortedListToBSTRecur(vec, mid + 1 , end);
return root;
}
static TNode sortedListToBST(LNode head) {
List<Integer> vec = new ArrayList<Integer>();
LNode temp = head;
while (temp != null ) {
vec.add(temp.data);
temp = temp.next;
}
return sortedListToBSTRecur(vec, 0 , vec.size() - 1 );
}
public static void main(String[] args) {
LNode head = new LNode( 1 );
head.next = new LNode( 2 );
head.next.next = new LNode( 3 );
head.next.next.next = new LNode( 4 );
head.next.next.next.next = new LNode( 5 );
head.next.next.next.next.next = new LNode( 6 );
head.next.next.next.next.next.next = new LNode( 7 );
System.out.println( "Given Linked List: " );
printList(head);
System.out.println();
TNode root = sortedListToBST(head);
System.out.println( "Preorder Traversal of constructed BST: " );
preOrder(root);
}
}
|
Python
class LNode:
def __init__( self , data):
self .data = data
self . next = None
class TNode:
def __init__( self , data):
self .data = data
self .left = None
self .right = None
def printList(node):
while (node is not None ):
print (node.data)
node = node. next
def preOrder(root):
if (root is None ):
return
print (root.data)
preOrder(root.left)
preOrder(root.right)
def sortedListToBSTRecur(vec, start, end):
if (start > end):
return None
mid = start + ( int )((end - start) / 2 )
if ((end - start) % 2 ! = 0 ):
mid = mid + 1
root = TNode(vec[mid])
root.left = sortedListToBSTRecur(vec, start, mid - 1 )
root.right = sortedListToBSTRecur(vec, mid + 1 , end)
return root
def sortedListToBST(head):
vec = []
temp = head
while (temp is not None ):
vec.append(temp.data)
temp = temp. next
return sortedListToBSTRecur(vec, 0 , len (vec) - 1 )
head = LNode( 1 )
head. next = LNode( 2 )
head. next . next = LNode( 3 )
head. next . next . next = LNode( 4 )
head. next . next . next . next = LNode( 5 )
head. next . next . next . next . next = LNode( 6 )
head. next . next . next . next . next . next = LNode( 7 )
print ( "Given Linked List : " )
printList(head)
print ( " " )
root = sortedListToBST(head)
print ( "PreOrder Traversal of constructed BST : " )
preOrder(root)
|
C#
using System;
using System.Collections.Generic;
class LNode {
public int data;
public LNode next;
public LNode( int data) {
this .data = data;
this .next = null ;
}
}
class TNode {
public int data;
public TNode left;
public TNode right;
public TNode( int data) {
this .data = data;
this .left = null ;
this .right = null ;
}
}
public class MainClass {
static void printList(LNode node) {
while (node != null ) {
Console.Write(node.data + " " );
node = node.next;
}
}
static void preOrder(TNode root) {
if (root == null ) {
return ;
}
Console.Write(root.data + " " );
preOrder(root.left);
preOrder(root.right);
}
static TNode sortedListToBSTRecur(List< int > vec, int start, int end) {
if (start > end) {
return null ;
}
int mid = start + (end - start) / 2;
if ((end - start) % 2 != 0) {
mid = mid + 1;
}
TNode root = new TNode(vec[mid]);
root.left = sortedListToBSTRecur(vec, start, mid - 1);
root.right = sortedListToBSTRecur(vec, mid + 1, end);
return root;
}
static TNode sortedListToBST(LNode head) {
List< int > vec = new List< int >();
LNode temp = head;
while (temp != null ) {
vec.Add(temp.data);
temp = temp.next;
}
return sortedListToBSTRecur(vec, 0, vec.Count - 1);
}
public static void Main( string [] args) {
LNode head = new LNode(1);
head.next = new LNode(2);
head.next.next = new LNode(3);
head.next.next.next = new LNode(4);
head.next.next.next.next = new LNode(5);
head.next.next.next.next.next = new LNode(6);
head.next.next.next.next.next.next = new LNode(7);
Console.WriteLine( "Given Linked List: " );
printList(head);
Console.WriteLine();
TNode root = sortedListToBST(head);
Console.WriteLine( "Preorder Traversal of constructed BST: " );
preOrder(root);
}
}
|
Javascript
class LNode{
constructor(data){
this .data = data;
this .next = null ;
}
}
class TNode{
constructor(data){
this .data = data;
this .left = null ;
this .right = null ;
}
}
function printList(node){
while (node != null ){
console.log(node.data + " " );
node = node.next;
}
}
function preOrder(root){
if (root == null ) return ;
console.log(root.data + " " );
preOrder(root.left);
preOrder(root.right);
}
function sortedListToBSTRecur(vec, start, end){
if (start > end) return null ;
let mid = start + (end-start)/2;
if ((end-start)%2 != 0) mid = mid+1;
let root = new TNode(vec[mid]);
root.left = sortedListToBSTRecur(vec, start, mid-1);
root.right = sortedListToBSTRecur(vec, mid+1, end);
return root;
}
function sortedListToBST(head){
let vec = [];
let temp = head;
while (temp != null ){
vec.push(temp.data);
temp = temp.next;
}
return sortedListToBSTRecur(vec, 0, vec.length - 1);
}
let head = new LNode(1);
head.next = new LNode(2);
head.next.next = new LNode(3);
head.next.next.next = new LNode(4);
head.next.next.next.next = new LNode(5);
head.next.next.next.next.next = new LNode(6);
head.next.next.next.next.next.next = new LNode(7);
console.log( "Given Linked List: " );
printList(head);
console.log( " " );
let root = sortedListToBST(head);
console.log( "PreOrder Traversal of constructed BST: " );
preOrder(root);
|
Output
Given Linked List:
1 2 3 4 5 6 7
Peorder Traversal of constructed BST:
4 2 1 3 6 5 7
Time Complexity: O(N) where N is the number of elements in given linked list.
Auxiliary Space: O(N)
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
06 Apr, 2023
Like Article
Save Article