Find median of BST

Last Updated : 14 Oct, 2025

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:

2

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:

1

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.

Try It Yourself
redirect icon

[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>
using namespace std;

// Node structure
class Node {
  public:
    int data;
    Node* left;
    Node* right;
    Node(int val) {
        data = val;
        left = right = nullptr;
    }
};
//Driver Code Ends


// Recursive Function for inorder
void getInorder(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 BST
int findMedian(Node* root) {
    vector<int> inorder;
    getInorder(root, inorder);
    int n = inorder.size();
    
    // n is even - 0 based indexing
    if (n % 2 == 0)
        return inorder[n/2-1];
        
    // n is odd - 0 based indexing
    else
        return inorder[n/2];
}


//Driver Code Starts
int main() {
    // Create BST:
    //            20
    //           /  \
    //          8    22
    //        /   \     
    //       4    12   
    //           /   \   
    //         10    14 
    
    Node* root = new Node(20);
    root->left = new Node(8);
    root->right = new Node(22);
    root->left->left = new Node(4);
    root->left->right = new Node(12);
    root->left->right->left = new Node(10);
    root->left->right->right = new Node(14);

    cout << findMedian(root) << endl;
    return 0;
}

//Driver Code Ends
Java
//Driver Code Starts
import java.util.ArrayList;
import java.util.List;

// Node structure
class Node {
    int data;
    Node left, right;

    Node(int val) {
        data = val;
        left = right = null;
    }
}

class GFG {
//Driver Code Ends

    
    // Recursive Function for inorder
    static void getInorder(Node node, ArrayList<Integer> traversal ) {
        if (node == null)
            return;
            
        getInorder(node.left, traversal);
        traversal.add(node.data);
        getInorder(node.right, traversal);
    }
    
    
    // Function to return Median of BST
    static int findMedian(Node root) {
        ArrayList<Integer> inorder = new ArrayList<>();
        getInorder(root, inorder);
        
        
        int n = inorder.size();
        
        // n is even - 0 based indexing
        if( n % 2 == 0 ) return inorder.get(n/2-1);
        
        // n is odd - 0 based indexing
        else return inorder.get(n/2);
    }
    

//Driver Code Starts
    public static void main(String[] args) { 
    
        // Create BST:
        //            20
        //           /  \
        //          8    22
        //        /   \     
        //       4    12   
        //           /   \   
        //         10    14  
        
        Node root = new Node(20);
        root.left = new Node(8);
        root.right = new Node(22);
        root.left.left = new Node(4);
        root.left.right = new Node(12);
        root.left.right.left = new Node(10);
        root.left.right.right = new Node(14);
    
        System.out.println(findMedian(root)); 
    }
}
//Driver Code Ends
Python
#Driver Code Starts
#  Node structure
class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None
#Driver Code Ends


# Recursive Function for inorder
def getInorder(node, traversal):
    if node is None:
        return
    getInorder(node.left, traversal)
    traversal.append(node.data)
    getInorder(node.right, traversal)

# Function to return Median of BST
def findMedian(root):
    inorder = []
    getInorder(root, inorder)
    n = len(inorder)
    
    #  n is even - 0 based indexing
    if n % 2 == 0:
        return inorder[n//2-1]
        
    # n is odd - 0 based indexing
    else:
        return inorder[n//2]


#Driver Code Starts
if __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 Starts
using System;
using System.Collections.Generic;

// Node structure
class Node {
    public int data;
    public Node left, right;
    public Node(int val) {
        data = val;
        left = right = null;
    }
}

class GFG {
//Driver Code Ends

    
    // Recursive Function for inorder
    static void getInorder(Node node, List<int> traversal) {
        if (node == null) return;
        
        getInorder(node.left, traversal);
        traversal.Add(node.data);
        getInorder(node.right, traversal);
    }
    
    
    // Function to return Median of BST
    static int findMedian(Node root) {
        List<int> inorder = new List<int>();
        getInorder(root, inorder);
        int n = inorder.Count;

        // n is even - 0 based indexing
        if (n % 2 == 0)
            return inorder[n/2-1];
            
        // n is odd - 0 based indexing
        else
            return inorder[n/2];
    }


//Driver Code Starts
    static void Main() {
        Node root = new Node(20);
        root.left = new Node(8);
        root.right = new Node(22);
        root.left.left = new Node(4);
        root.left.right = new Node(12);
        root.left.right.left = new Node(10);
        root.left.right.right = new Node(14);

        Console.WriteLine(findMedian(root));
    }
}

//Driver Code Ends
JavaScript
//Driver Code Starts
// Node structure
class Node {
    constructor(val) {
        this.data = val;
        this.left = null;
        this.right = null;
    }
}
//Driver Code Ends


// Recursive Function for inorder
function getInorder(node, traversal) {
    if (!node) return;

    getInorder(node.left, traversal);
    traversal.push(node.data);
    getInorder(node.right, traversal);
}

// Function to return Median of BST
function findMedian(root) {
    const inorder = [];
    getInorder(root, inorder);

    const n = inorder.length;
    
    // n is even - 0 based indexing
    if (n % 2 === 0) return inorder[n/2-1] ;
    
    // n is odd - 0 based indexing
    else return inorder[Math.floor(n/2)];
}


//Driver Code Starts
// Driver code

// Create BST:
//            20
//           /  \
//          8    22
//        /   \     
//       4    12   
//           /   \   
//         10    14  

const root = new Node(20);
root.left = new Node(8);
root.right = new Node(22);
root.left.left = new Node(4);
root.left.right = new Node(12);
root.left.right.left = new Node(10);
root.left.right.right = new Node(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>
using namespace std;

// Node structure
class Node {
public:
    int data;
    Node* left;
    Node* right;
    Node(int val) {
        data = val;
        left = right = nullptr;
    }
};
//Driver Code Ends


// Function to count number of Nodes in BST
int countNodes(Node* root) {
    Node* curr = root;
    int nodes = 0;
    while (curr != nullptr) {
        if (curr->left == nullptr) {
            nodes++;
            curr = curr->right;
        } else {
            
            // Find the inorder predecessor of curr
            Node* prev = curr->left;
            while (prev->right != nullptr && prev->right != curr) {
                prev = prev->right;
            }

            // Make curr the right child of its inorder predecessor
            if (prev->right == nullptr) {
                prev->right = curr;
                curr = curr->left;
            } else {
                
                // Revert the changes made in the tree structure
                prev->right = nullptr;
                curr = curr->right;
                nodes++;
            }
        }
    }
    return nodes;
}

// Function to find median of BST
int findMedian(Node* root) {
    int n = countNodes(root);
    int medianIndex;

    // 1 based index
    if (n % 2 == 0) medianIndex = n / 2;
    else medianIndex = (n + 1) / 2;

    Node* curr = root;
    int nodes = 0;
    while (curr != nullptr) {
        if (curr->left == nullptr) {
            nodes++;
            if (nodes == medianIndex) return curr->data;
            curr = curr->right;
        } else {
            
            // Find the inorder predecessor of curr
            Node* prev = curr->left;
            while (prev->right != nullptr && prev->right != curr) {
                prev = prev->right;
            }
            
            // Make curr the right child of its inorder predecessor
            if (prev->right == nullptr) {
                prev->right = curr;
                curr = curr->left;
            } else {
                nodes++;
                if (nodes == medianIndex) return curr->data;
                
                // Revert the changes made in the tree structure
                prev->right = nullptr;
                curr = curr->right;
            }
        }
    }
    return -1;
}


//Driver Code Starts
int main() {
    
    // Create BST:
    //         20
    //       /  \
    //      8    22
    //     /   \     
    //   4    12   
    //       /   \   
    //     10    14  
    
    Node* root = new Node(20);
    root->left = new Node(8);
    root->right = new Node(22);
    root->left->left = new Node(4);
    root->left->right = new Node(12);
    root->left->right->left = new Node(10);
    root->left->right->right = new Node(14);

    cout << findMedian(root);
}

//Driver Code Ends
Java
//Driver Code Starts
import java.util.ArrayList;
import java.util.List;

// Node Structure
class Node {
    int data;
    Node left, right;

    Node(int val) {
        data = val;
        left = right = null;
    }
}

class GFG { 
//Driver Code Ends

    
    // Function to count number of Nodes in BST
    static int countNodes(Node root) {
        Node curr = root;
        int nodes = 0;
        while (curr != null) {
            if (curr.left == null) {
                nodes++;
                curr = curr.right;
            } 
            else {
              
                // Find the inorder predecessor of curr
                Node prev = curr.left;
                while (prev.right != null && 
                                   prev.right != curr) {
                    prev = prev.right;
                }

                // Make curr the right child of its 
                // inorder predecessor
                if (prev.right == null) {
                    prev.right = curr;
                    curr = curr.left;
                } 
                else {
                    
                    // Revert the changes made in 
                    // the tree structure
                    prev.right = null;
                    curr = curr.right;
                    nodes++;
                }
            }
        }
        return nodes;
    }
    
    // Function to return Median of BST
    static int findMedian(Node root) {
        int n = countNodes(root);
        int medianIndex;
        
        // 1 based index
        if( n % 2 == 0) medianIndex = n/2;
        else medianIndex = (n+1)/2;
        
        Node curr = root;
        int nodes = 0;
        while (curr != null) {
            if (curr.left == null) {
                nodes++;
                if( nodes == medianIndex ) return curr.data;
                curr = curr.right;
            } 
            else {
                
                // Find the inorder predecessor of curr
                Node prev = curr.left;
                while (prev.right != null && 
                       prev.right != curr) {
                    prev = prev.right;
                }
                
                 // Make curr the right child of its inorder predecessor
                if (prev.right == null) {
                    prev.right = curr;
                    curr = curr.left;
                } 
                else {
                    nodes++;
                    if( nodes == medianIndex ) return curr.data;
                    
                    // Revert the changes made in the tree structure
                    prev.right = null;
                    curr = curr.right;
                }
            }
        }
        return -1;
    }
    

//Driver Code Starts
    public static void main(String[] args) {
        // Create BST:
        //         20
        //       /  \
        //      8    22
        //     /   \     
        //   4    12   
        //       /   \   
        //     10    14  
        
        Node root = new Node(20);
        root.left = new Node(8);
        root.right = new Node(22);
        root.left.left = new Node(4);
        root.left.right = new Node(12);
        root.left.right.left = new Node(10);
        root.left.right.right = new Node(14);
        
        System.out.println(findMedian(root));
    }
}
//Driver Code Ends
Python
#Driver Code Starts
#  Node structure
class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None
#Driver Code Ends


# Function to count number of Nodes in BST
def countNodes(root):
    curr = root
    nodes = 0
    while curr:
        if curr.left is None:
            nodes += 1
            curr = curr.right
        else:
            
            # Find the inorder predecessor of curr
            prev = curr.left
            while prev.right and prev.right != curr:
                prev = prev.right

            # Make curr the right child of its inorder predecessor
            if prev.right is None:
                prev.right = curr
                curr = curr.left
            else:
                
                # Revert the changes made in the tree structure
                prev.right = None
                curr = curr.right
                nodes += 1
    return nodes

# Function to return Median of BST
def findMedian(root):
    n = countNodes(root)
    
    # 1 based index
    if n % 2 == 0:
        medianIndex = n // 2
    else:
        medianIndex = (n + 1) // 2

    curr = root
    nodes = 0
    while curr:
        if curr.left is None:
            nodes += 1
            if nodes == medianIndex:
                return curr.data
            curr = curr.right
        else:
            
            # Find the inorder predecessor of curr
            prev = curr.left
            while prev.right and prev.right != curr:
                prev = prev.right
            
            # Make curr the right child of its inorder predecessor
            if prev.right is None:
                prev.right = curr
                curr = curr.left
            else:
                nodes += 1
                if nodes == medianIndex:
                    return curr.data
                    
                # Revert the changes made in the tree structure
                prev.right = None
                curr = curr.right
    return -1


#Driver Code Starts
            
if __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 Starts
using System;


// Node structure
class Node {
    public int data;
    public Node left, right;

    public Node(int val) {
        data = val;
        left = right = null;
    }
}

class GFG {
//Driver Code Ends

    
    // Function to count number of Nodes in BST
    static int countNodes(Node root) {
        Node curr = root;
        int nodes = 0;
        while (curr != null) {
            if (curr.left == null) {
                nodes++;
                curr = curr.right;
            } 
            else {
                
                // Find the inorder predecessor of curr
                Node prev = curr.left;
                while (prev.right != null && prev.right != curr) {
                    prev = prev.right;
                }

                // Make curr the right child of its inorder predecessor
                if (prev.right == null) {
                    prev.right = curr;
                    curr = curr.left;
                } 
                else {
                    
                    // Revert the changes made in the tree structure
                    prev.right = null;
                    curr = curr.right;
                    nodes++;
                }
            }
        }
        return nodes;
    }
    
    // Function to return Median of BST
    static int findMedian(Node root) {
        int n = countNodes(root);
        int medianIndex;

        // 1 based index
        if (n % 2 == 0) medianIndex = n / 2;
        else medianIndex = (n + 1) / 2;

        Node curr = root;
        int nodes = 0;
        while (curr != null) {
            if (curr.left == null) {
                nodes++;
                if (nodes == medianIndex) return curr.data;
                curr = curr.right;
            } 
            else {
                
                // Find the inorder predecessor of curr
                Node prev = curr.left;
                while (prev.right != null && prev.right != curr) {
                    prev = prev.right;
                }
                
                // Make curr the right child of its inorder predecessor
                if (prev.right == null) {
                    prev.right = curr;
                    curr = curr.left;
                } 
                else {
                    nodes++;
                    if (nodes == medianIndex) return curr.data;
                    
                    // Revert the changes made in the tree structure
                    prev.right = null;
                    curr = curr.right;
                }
            }
        }
        return -1;
    }


//Driver Code Starts
    public static void Main(string[] args) {
        
        // Create BST:
        //         20
        //       /  \
        //      8    22
        //     /   \     
        //   4    12   
        //       /   \   
        //     10    14  
        
        Node root = new Node(20);
        root.left = new Node(8);
        root.right = new Node(22);
        root.left.left = new Node(4);
        root.left.right = new Node(12);
        root.left.right.left = new Node(10);
        root.left.right.right = new Node(14);

        Console.WriteLine(findMedian(root));
    }
}
//Driver Code Ends
JavaScript
//Driver Code Starts
// Node structure
class Node {
    constructor(val) {
        this.data = val;
        this.left = null;
        this.right = null;
    }
}
//Driver Code Ends


// Function to count number of Nodes in BST
function countNodes(root) {
    let curr = root;
    let nodes = 0;
    while (curr !== null) {
        if (curr.left === null) {
            nodes++;
            curr = curr.right;
        } else {
            
            // Find the inorder predecessor of curr
            let prev = curr.left;
            while (prev.right !== null && prev.right !== curr) {
                prev = prev.right;
            }

            // Make curr the right child of its inorder predecessor
            if (prev.right === null) {
                prev.right = curr;
                curr = curr.left;
            } else {
                
                // Revert the changes made in the tree structure
                prev.right = null;
                curr = curr.right;
                nodes++;
            }
        }
    }
    return nodes;
}

// Function to return Median of BST
function findMedian(root) {
    let n = countNodes(root);
    let medianIndex;

    // 1 based index
    if (n % 2 === 0) medianIndex = n / 2;
    else medianIndex = (n + 1) / 2;

    let curr = root;
    let nodes = 0;
    while (curr !== null) {
        if (curr.left === null) {
            nodes++;
            if (nodes === medianIndex) return curr.data;
            curr = curr.right;
        } else {
            
            // Find the inorder predecessor of curr
            let prev = curr.left;
            while (prev.right !== null && prev.right !== curr) {
                prev = prev.right;
            }
    
            // Make curr the right child of its inorder predecessor
            if (prev.right === null) {
                prev.right = curr;
                curr = curr.left;
            } else {
                nodes++;
                if (nodes === medianIndex) return curr.data;
                
                // Revert the changes made in the tree structure
                prev.right = null;
                curr = curr.right;
            }
        }
    }
    return -1;
}


//Driver Code Starts
// Driver code

// Create BST
//         20
//       /  \
//      8    22
//     /   \     
//   4    12   
//       /   \   
//     10    14  

let root = new Node(20);
root.left = new Node(8);
root.right = new Node(22);
root.left.left = new Node(4);
root.left.right = new Node(12);
root.left.right.left = new Node(10);
root.left.right.right = new Node(14);

console.log(findMedian(root));
//Driver Code Ends

Output
12


Comment