Maximum in a Binary Search Tree
Given a Binary Search Tree, the task is to find the node with the maximum value in a BST.
Example:
Input:
Output : 7
Input:
Output: 20
Table of Content
[Naive Approach] Using Inorder Traversal – O(n) Time and O(n) Space
The idea is to use the property of BST which says inorder traversal of a binary search tree always returns the value of nodes in sorted order. So the last value in the sorted vector will be the maximumvalue which is the answer.
Below is the implementation of the above approach:
#include <iostream>
#include <vector>
using namespace std;
class Node {
public:
int data;
Node* left;
Node* right;
Node(int val) : data(val), left(nullptr), right(nullptr) {}
};
void inorder(Node* root, vector<int>& sorted_inorder) {
if (root == nullptr) return;
// Traverse left subtree
inorder(root->left, sorted_inorder);
// Store the current node's data
sorted_inorder.push_back(root->data);
// Traverse right subtree
inorder(root->right, sorted_inorder);
}
int maxValue(Node* root) {
if (root == nullptr) return -1;
// Using a vector to hold inorder elements
vector<int> sorted_inorder;
// Call the recursive inorder function
inorder(root, sorted_inorder);
// Return the last element, which is the maximum
return sorted_inorder.back();
}
int main() {
// Representation of input binary search tree
// 5
// / \
// 4 6
// / \
// 3 7
// /
// 1
Node* root = new Node(5);
root->left = new Node(4);
root->right = new Node(6);
root->left->left = new Node(3);
root->right->right = new Node(7);
root->left->left->left = new Node(1);
cout << maxValue(root) << endl;
return 0;
}
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* left;
struct Node* right;
};
void inorder(struct Node* root, int* sorted_inorder, int* index) {
// Base Case
if (root == NULL) {
return;
}
// Traverse left subtree
inorder(root->left, sorted_inorder, index);
// Store the current node's data
sorted_inorder[(*index)++] = root->data;
// Traverse right subtree
inorder(root->right, sorted_inorder, index);
}
int maxValue(struct Node* root) {
if (root == NULL) {
return -1;
}
// Using an array to hold inorder elements
int sorted_inorder[100]; // Assuming a maximum of 100 nodes
int index = 0;
// Call the recursive inorder function
inorder(root, sorted_inorder, &index);
// Return the last element, which is the maximum
return sorted_inorder[index - 1];
}
int main() {
// Representation of input binary search tree
// 5
// / \
// 4 6
// / \
// 3 7
// /
// 1
struct Node* root = (struct Node*)malloc(sizeof(struct Node));
root->data = 5;
root->left = (struct Node*)malloc(sizeof(struct Node));
root->left->data = 4;
root->right = (struct Node*)malloc(sizeof(struct Node));
root->right->data = 6;
root->left->left = (struct Node*)malloc(sizeof(struct Node));
root->left->left->data = 3;
root->right->right = (struct Node*)malloc(sizeof(struct Node));
root->right->right->data = 7;
root->left->left->left = (struct Node*)malloc(sizeof(struct Node));
root->left->left->left->data = 1;
printf("%d\n", maxValue(root));
return 0;
}
class Node {
int data;
Node left, right;
Node(int item) {
data = item;
left = right = null;
}
}
public class BinaryTree {
Node root;
void inorder(Node node, List<Integer> sortedInorder) {
// Base Case
if (node == null) {
return;
}
// Traverse left subtree
inorder(node.left, sortedInorder);
// Store the current node's data
sortedInorder.add(node.data);
// Traverse right subtree
inorder(node.right, sortedInorder);
}
int maxValue(Node node) {
if (node == null) {
return -1;
}
// Using a list to hold inorder elements
List<Integer> sortedInorder = new ArrayList<>();
// Call the recursive inorder function
inorder(node, sortedInorder);
// Return the last element, which is the maximum
return sortedInorder.get(sortedInorder.size() - 1);
}
public static void main(String[] args) {
BinaryTree tree = new BinaryTree();
// Representation of input binary search tree
// 5
// / \
// 4 6
// / \
// 3 7
// /
// 1
tree.root = new Node(5);
tree.root.left = new Node(4);
tree.root.right = new Node(6);
tree.root.left.left = new Node(3);
tree.root.right.right = new Node(7);
tree.root.left.left.left = new Node(1);
System.out.println(tree.maxValue(tree.root));
}
}
class Node:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
def inorder(root, sorted_inorder):
# Base Case
if root is None:
return
# Traverse left subtree
inorder(root.left, sorted_inorder)
# Store the current node's data
sorted_inorder.append(root.data)
# Traverse right subtree
inorder(root.right, sorted_inorder)
def maxValue(root):
if root is None:
return -1
# Using a list to hold inorder elements
sorted_inorder = []
# Call the recursive inorder function
inorder(root, sorted_inorder)
# Return the last element, which is the maximum
return sorted_inorder[-1]
if __name__ == "__main__":
# Representation of input binary search tree
# 5
# / \
# 4 6
# / \
# 3 7
# /
# 1
root = Node(5)
root.left = Node(4)
root.right = Node(6)
root.left.left = Node(3)
root.right.right = Node(7)
root.left.left.left = Node(1)
print(maxValue(root))
using System;
using System.Collections.Generic;
class Node {
public int data;
public Node left;
public Node right;
public Node(int data) {
this.data = data;
this.left = null;
this.right = null;
}
}
class Program {
static void Inorder(Node root, List<int> sortedInorder) {
// Base Case
if (root == null) {
return;
}
// Traverse left subtree
Inorder(root.left, sortedInorder);
// Store the current node's data
sortedInorder.Add(root.data);
// Traverse right subtree
Inorder(root.right, sortedInorder);
}
static int MaxValue(Node root) {
if (root == null) {
return -1;
}
// Using a list to hold inorder elements
List<int> sortedInorder = new List<int>();
// Call the recursive inorder function
Inorder(root, sortedInorder);
// Return the last element, which is the maximum
return sortedInorder[sortedInorder.Count - 1];
}
static void Main() {
// Representation of input binary search tree
// 5
// / \
// 4 6
// / \
// 3 7
// /
// 1
Node root = new Node(5);
root.left = new Node(4);
root.right = new Node(6);
root.left.left = new Node(3);
root.right.right = new Node(7);
root.left.left.left = new Node(1);
Console.WriteLine(MaxValue(root));
}
}
class Node {
constructor(data) {
this.data = data;
this.left = null;
this.right = null;
}
}
function inorder(root, sorted_inorder) {
// Base Case
if (root === null) {
return;
}
// Traverse left subtree
inorder(root.left, sorted_inorder);
// Store the current node's data
sorted_inorder.push(root.data);
// Traverse right subtree
inorder(root.right, sorted_inorder);
}
function maxValue(root) {
if (root === null) {
return -1;
}
// Using an array to hold inorder elements
let sorted_inorder = [];
// Call the recursive inorder function
inorder(root, sorted_inorder);
// Return the last element, which is the maximum
return sorted_inorder[sorted_inorder.length - 1];
}
// Representation of input binary search tree
// 5
// / \
// 4 6
// / \
// 3 7
// /
// 1
let root = new Node(5);
root.left = new Node(4);
root.right = new Node(6);
root.left.left = new Node(3);
root.right.right = new Node(7);
root.left.left.left = new Node(1);
console.log(maxValue(root));
Output
7
Time Complexity: O(n), where n is the number of nodes in BST.
Auxiliary Space: O(n)
[Expected Approach] Traversing Across Right Edges Only – O(h) Time and O(1) Space
The idea is that in a Binary Search Tree (BST), the right child of a node is always larger than the root. This ensures that the node whose right pointer is NULL must hold the maximum value in the tree. The rightmost node will always contain the largest element.
Below is the implementation of the above approach:
#include <iostream>
using namespace std;
class Node {
public:
int data;
Node* left;
Node* right;
Node(int value) : data(value), left(NULL), right(NULL) {}
};
// Function to find the maximum value in BST
int maxValue(Node* root) {
// Base case
if (root == NULL) {
return -1;
}
Node* curr = root;
// Rightmost node is maximum, so move
// till right is not NULL
while (curr->right != NULL) {
curr = curr->right;
}
// Returning the data at the rightmost node
return curr->data;
}
int main() {
// Representation of input binary search tree
// 5
// / \
// 4 6
// / \
// 3 7
// /
// 1
Node* root = new Node(5);
root->left = new Node(4);
root->right = new Node(6);
root->left->left = new Node(3);
root->right->right = new Node(7);
root->left->left->left = new Node(1);
cout << maxValue(root) << endl;
return 0;
}
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* left;
struct Node* right;
};
// Function to find the maximum value in BST
int maxValue(struct Node* root) {
// Base case
if (root == NULL) {
return -1;
}
struct Node* curr = root;
// Rightmost node is maximum, so move
// till right is not NULL
while (curr->right != NULL) {
curr = curr->right;
}
// Returning the data at the rightmost node
return curr->data;
}
int main() {
// Representation of input binary search tree
// 5
// / \
// 4 6
// / \
// 3 7
// /
// 1
struct Node* root = (struct Node*)malloc(sizeof(struct Node));
root->data = 5;
root->left = (struct Node*)malloc(sizeof(struct Node));
root->left->data = 4;
root->right = (struct Node*)malloc(sizeof(struct Node));
root->right->data = 6;
root->left->left = (struct Node*)malloc(sizeof(struct Node));
root->left->left->data = 3;
root->right->right = (struct Node*)malloc(sizeof(struct Node));
root->right->right->data = 7;
root->left->left->left = (struct Node*)malloc(sizeof(struct Node));
root->left->left->left->data = 1;
printf("%d\n", maxValue(root));
return 0;
}
class Node {
int data;
Node left, right;
Node(int value) {
data = value;
left = right = null;
}
}
// Function to find the maximum value in BST
int maxValue(Node root) {
// Base case
if (root == null) {
return -1;
}
Node curr = root;
// Rightmost node is maximum, so move
// till right is not null
while (curr.right != null) {
curr = curr.right;
}
// Returning the data at the rightmost node
return curr.data;
}
public static void main(String[] args) {
// Representation of input binary search tree
// 5
// / \
// 4 6
// / \
// 3 7
// /
// 1
Node root = new Node(5);
root.left = new Node(4);
root.right = new Node(6);
root.left.left = new Node(3);
root.right.right = new Node(7);
root.left.left.left = new Node(1);
System.out.println(maxValue(root));
}
class Node:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
# Function to find the maximum value in BST
def maxValue(root):
# Base case
if root is None:
return -1
curr = root
# Rightmost node is maximum, so move
# till right is not None
while curr.right is not None:
curr = curr.right
# Returning the data at the rightmost node
return curr.data
if __name__ == "__main__":
# Representation of input binary search tree
# 5
# / \
# 4 6
# / \
# 3 7
# /
# 1
root = Node(5)
root.left = Node(4)
root.right = Node(6)
root.left.left = Node(3)
root.right.right = Node(7)
root.left.left.left = Node(1)
print(maxValue(root))
using System;
class Node {
public int data;
public Node left, right;
public Node(int value) {
data = value;
left = right = null;
}
}
// Function to find the maximum value in BST
public static int maxValue(Node root) {
// Base case
if (root == null) {
return -1;
}
Node curr = root;
// Rightmost node is maximum, so move
// till right is not null
while (curr.right != null) {
curr = curr.right;
}
// Returning the data at the rightmost node
return curr.data;
}
public static void Main() {
// Representation of input binary search tree
// 5
// / \
// 4 6
// / \
// 3 7
// /
// 1
Node root = new Node(5);
root.left = new Node(4);
root.right = new Node(6);
root.left.left = new Node(3);
root.right.right = new Node(7);
root.left.left.left = new Node(1);
Console.WriteLine(maxValue(root));
}
// Node class definition
class Node {
constructor(data) {
this.data = data;
this.left = null;
this.right = null;
}
}
// Function to find the maximum value in BST
function maxValue(root) {
// Base case
if (root === null) {
return -1;
}
let curr = root;
// Rightmost node is maximum, so move
// till right is not null
while (curr.right !== null) {
curr = curr.right;
}
// Returning the data at the rightmost node
return curr.data;
}
// Representation of input binary search tree
// 5
// / \
// 4 6
// / \
// 3 7
// /
// 1
let root = new Node(5);
root.left = new Node(4);
root.right = new Node(6);
root.left.left = new Node(3);
root.right.right = new Node(7);
root.left.left.left = new Node(1);
console.log(maxValue(root));
Output
7
Time Complexity: O(h) In the worst case where h is the height of the Binary Search Tree
Auxiliary Space: O(1)