Given the root of a Binary Search Tree, find the median of it.
Let the nodes of the BST, when written in ascending order (inorder traversal), be represented as V1, V2, V3, …, Vn, where n is the total number of nodes in the BST.
If number of nodes are even: return V(n/2)
If number of nodes are odd: return V((n+1)/2)
Examples:
Input:
Output: 12 Explanation: The inorder of given BST is 4, 8, 10, 12, 14, 20, 22. Here, n = 7, so, here median will be ((7+1)/2)th value, i.e., 4th value, i.e, 12.
Input:
Output: 4 Explanation: The inorder of given BST is 1, 4, 5, 8. Here, n = 4(even), so, here median will be (4/2)th value, i.e., 2nd value, i.e, 4.
[Approach 1] Median Of BST using Inorder Traversal - O(n) Time and O(n) Space
The idea is based on the property of BST, i.e., inorder traversal of BST gives a sorted list. We will store the inorder traversal of the BST and return the median.
C++
//Driver Code Starts#include<iostream>#include<vector>usingnamespacestd;// Node structureclassNode{public:intdata;Node*left;Node*right;Node(intval){data=val;left=right=nullptr;}};//Driver Code Ends// Recursive Function for inordervoidgetInorder(Node*node,vector<int>&traversal){if(!node)return;getInorder(node->left,traversal);traversal.push_back(node->data);getInorder(node->right,traversal);}// Function to return Median of BSTintfindMedian(Node*root){vector<int>inorder;getInorder(root,inorder);intn=inorder.size();// n is even - 0 based indexingif(n%2==0)returninorder[n/2-1];// n is odd - 0 based indexingelsereturninorder[n/2];}//Driver Code Startsintmain(){// Create BST:// 20// / \ // 8 22// / \ // 4 12 // / \ // 10 14 Node*root=newNode(20);root->left=newNode(8);root->right=newNode(22);root->left->left=newNode(4);root->left->right=newNode(12);root->left->right->left=newNode(10);root->left->right->right=newNode(14);cout<<findMedian(root)<<endl;return0;}//Driver Code Ends
Java
//Driver Code Startsimportjava.util.ArrayList;importjava.util.List;// Node structureclassNode{intdata;Nodeleft,right;Node(intval){data=val;left=right=null;}}classGFG{//Driver Code Ends// Recursive Function for inorderstaticvoidgetInorder(Nodenode,ArrayList<Integer>traversal){if(node==null)return;getInorder(node.left,traversal);traversal.add(node.data);getInorder(node.right,traversal);}// Function to return Median of BSTstaticintfindMedian(Noderoot){ArrayList<Integer>inorder=newArrayList<>();getInorder(root,inorder);intn=inorder.size();// n is even - 0 based indexingif(n%2==0)returninorder.get(n/2-1);// n is odd - 0 based indexingelsereturninorder.get(n/2);}//Driver Code Startspublicstaticvoidmain(String[]args){// Create BST:// 20// / \// 8 22// / \ // 4 12 // / \ // 10 14 Noderoot=newNode(20);root.left=newNode(8);root.right=newNode(22);root.left.left=newNode(4);root.left.right=newNode(12);root.left.right.left=newNode(10);root.left.right.right=newNode(14);System.out.println(findMedian(root));}}//Driver Code Ends
Python
#Driver Code Starts# Node structureclassNode:def__init__(self,val):self.data=valself.left=Noneself.right=None#Driver Code Ends# Recursive Function for inorderdefgetInorder(node,traversal):ifnodeisNone:returngetInorder(node.left,traversal)traversal.append(node.data)getInorder(node.right,traversal)# Function to return Median of BSTdeffindMedian(root):inorder=[]getInorder(root,inorder)n=len(inorder)# n is even - 0 based indexingifn%2==0:returninorder[n//2-1]# n is odd - 0 based indexingelse:returninorder[n//2]#Driver Code Startsif__name__=="__main__":# Create BST:# 20# / \# 8 22# / \ # 4 12 # / \ # 10 14 root=Node(20)root.left=Node(8)root.right=Node(22)root.left.left=Node(4)root.left.right=Node(12)root.left.right.left=Node(10)root.left.right.right=Node(14)print(findMedian(root))#Driver Code Ends
C#
//Driver Code StartsusingSystem;usingSystem.Collections.Generic;// Node structureclassNode{publicintdata;publicNodeleft,right;publicNode(intval){data=val;left=right=null;}}classGFG{//Driver Code Ends// Recursive Function for inorderstaticvoidgetInorder(Nodenode,List<int>traversal){if(node==null)return;getInorder(node.left,traversal);traversal.Add(node.data);getInorder(node.right,traversal);}// Function to return Median of BSTstaticintfindMedian(Noderoot){List<int>inorder=newList<int>();getInorder(root,inorder);intn=inorder.Count;// n is even - 0 based indexingif(n%2==0)returninorder[n/2-1];// n is odd - 0 based indexingelsereturninorder[n/2];}//Driver Code StartsstaticvoidMain(){Noderoot=newNode(20);root.left=newNode(8);root.right=newNode(22);root.left.left=newNode(4);root.left.right=newNode(12);root.left.right.left=newNode(10);root.left.right.right=newNode(14);Console.WriteLine(findMedian(root));}}//Driver Code Ends
JavaScript
//Driver Code Starts// Node structureclassNode{constructor(val){this.data=val;this.left=null;this.right=null;}}//Driver Code Ends// Recursive Function for inorderfunctiongetInorder(node,traversal){if(!node)return;getInorder(node.left,traversal);traversal.push(node.data);getInorder(node.right,traversal);}// Function to return Median of BSTfunctionfindMedian(root){constinorder=[];getInorder(root,inorder);constn=inorder.length;// n is even - 0 based indexingif(n%2===0)returninorder[n/2-1];// n is odd - 0 based indexingelsereturninorder[Math.floor(n/2)];}//Driver Code Starts// Driver code// Create BST:// 20// / \// 8 22// / \ // 4 12 // / \ // 10 14 constroot=newNode(20);root.left=newNode(8);root.right=newNode(22);root.left.left=newNode(4);root.left.right=newNode(12);root.left.right.left=newNode(10);root.left.right.right=newNode(14);console.log(findMedian(root));//Driver Code Ends
Output
12
[Approach 2] Median Of BST using Morris Inorder Traversal - O(n) Time and O(1) Space
The idea is to perform an inorder traversal of the given Binary Search Tree using the Morris Traversal algorithm.
During the first traversal, we count the total number of nodes in the BST. Then, during the second traversal, we again perform Morris traversal while maintaining a counter for visited nodes. Once the counter reaches the middle position (depending on whether the number of nodes is odd or even), we return the value of the current node as the median.
C++
//Driver Code Starts#include<iostream>#include<vector>usingnamespacestd;// Node structureclassNode{public:intdata;Node*left;Node*right;Node(intval){data=val;left=right=nullptr;}};//Driver Code Ends// Function to count number of Nodes in BSTintcountNodes(Node*root){Node*curr=root;intnodes=0;while(curr!=nullptr){if(curr->left==nullptr){nodes++;curr=curr->right;}else{// Find the inorder predecessor of currNode*prev=curr->left;while(prev->right!=nullptr&&prev->right!=curr){prev=prev->right;}// Make curr the right child of its inorder predecessorif(prev->right==nullptr){prev->right=curr;curr=curr->left;}else{// Revert the changes made in the tree structureprev->right=nullptr;curr=curr->right;nodes++;}}}returnnodes;}// Function to find median of BSTintfindMedian(Node*root){intn=countNodes(root);intmedianIndex;// 1 based indexif(n%2==0)medianIndex=n/2;elsemedianIndex=(n+1)/2;Node*curr=root;intnodes=0;while(curr!=nullptr){if(curr->left==nullptr){nodes++;if(nodes==medianIndex)returncurr->data;curr=curr->right;}else{// Find the inorder predecessor of currNode*prev=curr->left;while(prev->right!=nullptr&&prev->right!=curr){prev=prev->right;}// Make curr the right child of its inorder predecessorif(prev->right==nullptr){prev->right=curr;curr=curr->left;}else{nodes++;if(nodes==medianIndex)returncurr->data;// Revert the changes made in the tree structureprev->right=nullptr;curr=curr->right;}}}return-1;}//Driver Code Startsintmain(){// Create BST:// 20// / \ // 8 22// / \ // 4 12 // / \ // 10 14 Node*root=newNode(20);root->left=newNode(8);root->right=newNode(22);root->left->left=newNode(4);root->left->right=newNode(12);root->left->right->left=newNode(10);root->left->right->right=newNode(14);cout<<findMedian(root);}//Driver Code Ends
Java
//Driver Code Startsimportjava.util.ArrayList;importjava.util.List;// Node StructureclassNode{intdata;Nodeleft,right;Node(intval){data=val;left=right=null;}}classGFG{//Driver Code Ends// Function to count number of Nodes in BSTstaticintcountNodes(Noderoot){Nodecurr=root;intnodes=0;while(curr!=null){if(curr.left==null){nodes++;curr=curr.right;}else{// Find the inorder predecessor of currNodeprev=curr.left;while(prev.right!=null&&prev.right!=curr){prev=prev.right;}// Make curr the right child of its // inorder predecessorif(prev.right==null){prev.right=curr;curr=curr.left;}else{// Revert the changes made in // the tree structureprev.right=null;curr=curr.right;nodes++;}}}returnnodes;}// Function to return Median of BSTstaticintfindMedian(Noderoot){intn=countNodes(root);intmedianIndex;// 1 based indexif(n%2==0)medianIndex=n/2;elsemedianIndex=(n+1)/2;Nodecurr=root;intnodes=0;while(curr!=null){if(curr.left==null){nodes++;if(nodes==medianIndex)returncurr.data;curr=curr.right;}else{// Find the inorder predecessor of currNodeprev=curr.left;while(prev.right!=null&&prev.right!=curr){prev=prev.right;}// Make curr the right child of its inorder predecessorif(prev.right==null){prev.right=curr;curr=curr.left;}else{nodes++;if(nodes==medianIndex)returncurr.data;// Revert the changes made in the tree structureprev.right=null;curr=curr.right;}}}return-1;}//Driver Code Startspublicstaticvoidmain(String[]args){// Create BST:// 20// / \// 8 22// / \ // 4 12 // / \ // 10 14 Noderoot=newNode(20);root.left=newNode(8);root.right=newNode(22);root.left.left=newNode(4);root.left.right=newNode(12);root.left.right.left=newNode(10);root.left.right.right=newNode(14);System.out.println(findMedian(root));}}//Driver Code Ends
Python
#Driver Code Starts# Node structureclassNode:def__init__(self,val):self.data=valself.left=Noneself.right=None#Driver Code Ends# Function to count number of Nodes in BSTdefcountNodes(root):curr=rootnodes=0whilecurr:ifcurr.leftisNone:nodes+=1curr=curr.rightelse:# Find the inorder predecessor of currprev=curr.leftwhileprev.rightandprev.right!=curr:prev=prev.right# Make curr the right child of its inorder predecessorifprev.rightisNone:prev.right=currcurr=curr.leftelse:# Revert the changes made in the tree structureprev.right=Nonecurr=curr.rightnodes+=1returnnodes# Function to return Median of BSTdeffindMedian(root):n=countNodes(root)# 1 based indexifn%2==0:medianIndex=n//2else:medianIndex=(n+1)//2curr=rootnodes=0whilecurr:ifcurr.leftisNone:nodes+=1ifnodes==medianIndex:returncurr.datacurr=curr.rightelse:# Find the inorder predecessor of currprev=curr.leftwhileprev.rightandprev.right!=curr:prev=prev.right# Make curr the right child of its inorder predecessorifprev.rightisNone:prev.right=currcurr=curr.leftelse:nodes+=1ifnodes==medianIndex:returncurr.data# Revert the changes made in the tree structureprev.right=Nonecurr=curr.rightreturn-1#Driver Code Startsif__name__=="__main__":# Create BST# 20# / \# 8 22# / \ # 4 12 # / \ # 10 14 root=Node(20)root.left=Node(8)root.right=Node(22)root.left.left=Node(4)root.left.right=Node(12)root.left.right.left=Node(10)root.left.right.right=Node(14)print(findMedian(root))#Driver Code Ends
C#
//Driver Code StartsusingSystem;// Node structureclassNode{publicintdata;publicNodeleft,right;publicNode(intval){data=val;left=right=null;}}classGFG{//Driver Code Ends// Function to count number of Nodes in BSTstaticintcountNodes(Noderoot){Nodecurr=root;intnodes=0;while(curr!=null){if(curr.left==null){nodes++;curr=curr.right;}else{// Find the inorder predecessor of currNodeprev=curr.left;while(prev.right!=null&&prev.right!=curr){prev=prev.right;}// Make curr the right child of its inorder predecessorif(prev.right==null){prev.right=curr;curr=curr.left;}else{// Revert the changes made in the tree structureprev.right=null;curr=curr.right;nodes++;}}}returnnodes;}// Function to return Median of BSTstaticintfindMedian(Noderoot){intn=countNodes(root);intmedianIndex;// 1 based indexif(n%2==0)medianIndex=n/2;elsemedianIndex=(n+1)/2;Nodecurr=root;intnodes=0;while(curr!=null){if(curr.left==null){nodes++;if(nodes==medianIndex)returncurr.data;curr=curr.right;}else{// Find the inorder predecessor of currNodeprev=curr.left;while(prev.right!=null&&prev.right!=curr){prev=prev.right;}// Make curr the right child of its inorder predecessorif(prev.right==null){prev.right=curr;curr=curr.left;}else{nodes++;if(nodes==medianIndex)returncurr.data;// Revert the changes made in the tree structureprev.right=null;curr=curr.right;}}}return-1;}//Driver Code StartspublicstaticvoidMain(string[]args){// Create BST:// 20// / \// 8 22// / \ // 4 12 // / \ // 10 14 Noderoot=newNode(20);root.left=newNode(8);root.right=newNode(22);root.left.left=newNode(4);root.left.right=newNode(12);root.left.right.left=newNode(10);root.left.right.right=newNode(14);Console.WriteLine(findMedian(root));}}//Driver Code Ends
JavaScript
//Driver Code Starts// Node structureclassNode{constructor(val){this.data=val;this.left=null;this.right=null;}}//Driver Code Ends// Function to count number of Nodes in BSTfunctioncountNodes(root){letcurr=root;letnodes=0;while(curr!==null){if(curr.left===null){nodes++;curr=curr.right;}else{// Find the inorder predecessor of currletprev=curr.left;while(prev.right!==null&&prev.right!==curr){prev=prev.right;}// Make curr the right child of its inorder predecessorif(prev.right===null){prev.right=curr;curr=curr.left;}else{// Revert the changes made in the tree structureprev.right=null;curr=curr.right;nodes++;}}}returnnodes;}// Function to return Median of BSTfunctionfindMedian(root){letn=countNodes(root);letmedianIndex;// 1 based indexif(n%2===0)medianIndex=n/2;elsemedianIndex=(n+1)/2;letcurr=root;letnodes=0;while(curr!==null){if(curr.left===null){nodes++;if(nodes===medianIndex)returncurr.data;curr=curr.right;}else{// Find the inorder predecessor of currletprev=curr.left;while(prev.right!==null&&prev.right!==curr){prev=prev.right;}// Make curr the right child of its inorder predecessorif(prev.right===null){prev.right=curr;curr=curr.left;}else{nodes++;if(nodes===medianIndex)returncurr.data;// Revert the changes made in the tree structureprev.right=null;curr=curr.right;}}}return-1;}//Driver Code Starts// Driver code// Create BST// 20// / \// 8 22// / \ // 4 12 // / \ // 10 14 letroot=newNode(20);root.left=newNode(8);root.right=newNode(22);root.left.left=newNode(4);root.left.right=newNode(12);root.left.right.left=newNode(10);root.left.right.right=newNode(14);console.log(findMedian(root));//Driver Code Ends