Given a Binary Search Tree (BST), modify it so that all greater values in the given BST are added to every node. For example, consider the following BST.
50
/ \
30 70
/ \ / \
20 40 60 80
The above tree should be modified to following
260
/ \
330 150
/ \ / \
350 300 210 80
A simple method for solving this is to find the sum of all greater values for every node. This method would take O(n^2) time.
The method discussed in this article uses the technique of reverse in-order tree traversal of BST which optimizes the problem to be solved in a single traversal.
Approach: In this problem as we could notice that the largest node would remain the same. The value of 2nd largest node = value of largest + value of second largest node. Similarly, the value of nth largest node will be the sum of the n-th node and value of (n-1)th largest node after modification. So if we traverse the tree in descending order and simultaneously update the sum value at every step while adding the value to the root node, the problem would be solved.
So to traverse the BST in descending order we use reverse in-order traversal of BST. This takes a global variable sum which is updated at every node and once the root node is reached it is added to the value of root node and value of the root node is updated.
C++
#include <bits/stdc++.h>
using namespace std;
class Node {
public :
int data;
Node *left, *right;
};
Node* newNode( int item)
{
Node* temp = new Node();
temp->data = item;
temp->left = temp->right = NULL;
return temp;
}
void modifyBSTUtil(Node* root, int * sum)
{
if (root == NULL)
return ;
modifyBSTUtil(root->right, sum);
*sum = *sum + root->data;
root->data = *sum;
modifyBSTUtil(root->left, sum);
}
void modifyBST(Node* root)
{
int sum = 0;
modifyBSTUtil(root, &sum);
}
void inorder(Node* root)
{
if (root != NULL) {
inorder(root->left);
cout << root->data << " " ;
inorder(root->right);
}
}
Node* insert(Node* node, int data)
{
if (node == NULL)
return newNode(data);
if (data <= node->data)
node->left = insert(node->left, data);
else
node->right = insert(node->right, data);
return node;
}
int main()
{
Node* root = NULL;
root = insert(root, 50);
insert(root, 30);
insert(root, 20);
insert(root, 40);
insert(root, 70);
insert(root, 60);
insert(root, 80);
modifyBST(root);
inorder(root);
return 0;
}
|
C
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *left, *right;
};
struct Node* newNode( int item)
{
struct Node* temp
= ( struct Node*) malloc (
sizeof ( struct Node));
temp->data = item;
temp->left = temp->right = NULL;
return temp;
}
void modifyBSTUtil(
struct Node* root, int * sum)
{
if (root == NULL)
return ;
modifyBSTUtil(root->right, sum);
*sum = *sum + root->data;
root->data = *sum;
modifyBSTUtil(root->left, sum);
}
void modifyBST( struct Node* root)
{
int sum = 0;
modifyBSTUtil(root, &sum);
}
void inorder( struct Node* root)
{
if (root != NULL) {
inorder(root->left);
printf ( "%d " , root->data);
inorder(root->right);
}
}
struct Node* insert(
struct Node* node, int data)
{
if (node == NULL)
return newNode(data);
if (data <= node->data)
node->left = insert(node->left, data);
else
node->right = insert(node->right, data);
return node;
}
int main()
{
struct Node* root = NULL;
root = insert(root, 50);
insert(root, 30);
insert(root, 20);
insert(root, 40);
insert(root, 70);
insert(root, 60);
insert(root, 80);
modifyBST(root);
inorder(root);
return 0;
}
|
Java
class Node {
int data;
Node left, right;
Node( int d)
{
data = d;
left = right = null ;
}
}
class BinarySearchTree {
Node root;
BinarySearchTree()
{
root = null ;
}
void inorder()
{
inorderUtil( this .root);
}
void inorderUtil(Node node)
{
if (node == null )
return ;
inorderUtil(node.left);
System.out.print(node.data + " " );
inorderUtil(node.right);
}
public void insert( int data)
{
this .root = this .insertRec( this .root, data);
}
Node insertRec(Node node, int data)
{
if (node == null ) {
this .root = new Node(data);
return this .root;
}
if (data <= node.data) {
node.left = this .insertRec(node.left, data);
}
else {
node.right = this .insertRec(node.right, data);
}
return node;
}
public class Sum {
int sum = 0 ;
}
void modifyBSTUtil(Node node, Sum S)
{
if (node == null )
return ;
this .modifyBSTUtil(node.right, S);
S.sum = S.sum + node.data;
node.data = S.sum;
this .modifyBSTUtil(node.left, S);
}
void modifyBST(Node node)
{
Sum S = new Sum();
this .modifyBSTUtil(node, S);
}
public static void main(String[] args)
{
BinarySearchTree tree = new BinarySearchTree();
tree.insert( 50 );
tree.insert( 30 );
tree.insert( 20 );
tree.insert( 40 );
tree.insert( 70 );
tree.insert( 60 );
tree.insert( 80 );
tree.modifyBST(tree.root);
tree.inorder();
}
}
|
Python3
class newNode:
def __init__( self , data):
self .data = data
self .left = None
self .right = None
def modifyBSTUtil(root, Sum ):
if root = = None :
return
modifyBSTUtil(root.right, Sum )
Sum [ 0 ] = Sum [ 0 ] + root.data
root.data = Sum [ 0 ]
modifyBSTUtil(root.left, Sum )
def modifyBST(root):
Sum = [ 0 ]
modifyBSTUtil(root, Sum )
def inorder(root):
if root ! = None :
inorder(root.left)
print (root.data, end = " " )
inorder(root.right)
def insert(node, data):
if node = = None :
return newNode(data)
if data < = node.data:
node.left = insert(node.left, data)
else :
node.right = insert(node.right, data)
return node
if __name__ = = '__main__' :
root = None
root = insert(root, 50 )
insert(root, 30 )
insert(root, 20 )
insert(root, 40 )
insert(root, 70 )
insert(root, 60 )
insert(root, 80 )
modifyBST(root)
inorder(root)
|
C#
using System;
public class Node {
public int data;
public Node left, right;
public Node( int d)
{
data = d;
left = right = null ;
}
}
public class BinarySearchTree {
public Node root;
public BinarySearchTree()
{
root = null ;
}
public virtual void inorder()
{
inorderUtil( this .root);
}
public virtual void inorderUtil(Node node)
{
if (node == null ) {
return ;
}
inorderUtil(node.left);
Console.Write(node.data + " " );
inorderUtil(node.right);
}
public virtual void insert( int data)
{
this .root = this .insertRec( this .root, data);
}
public virtual Node insertRec(Node node, int data)
{
if (node == null ) {
this .root = new Node(data);
return this .root;
}
if (data <= node.data) {
node.left = this .insertRec(node.left, data);
}
else {
node.right = this .insertRec(node.right, data);
}
return node;
}
public class Sum {
private readonly BinarySearchTree outerInstance;
public Sum(BinarySearchTree outerInstance)
{
this .outerInstance = outerInstance;
}
public int sum = 0;
}
public virtual void modifyBSTUtil(Node node, Sum S)
{
if (node == null ) {
return ;
}
this .modifyBSTUtil(node.right, S);
S.sum = S.sum + node.data;
node.data = S.sum;
this .modifyBSTUtil(node.left, S);
}
public virtual void modifyBST(Node node)
{
Sum S = new Sum( this );
this .modifyBSTUtil(node, S);
}
public static void Main( string [] args)
{
BinarySearchTree tree = new BinarySearchTree();
tree.insert(50);
tree.insert(30);
tree.insert(20);
tree.insert(40);
tree.insert(70);
tree.insert(60);
tree.insert(80);
tree.modifyBST(tree.root);
tree.inorder();
}
}
|
Javascript
<script>
class Node {
constructor(val) {
this .data = val;
this .left = null ;
this .right = null ;
}
}
var root = null ;
function inorder()
{
inorderUtil( this .root);
}
function inorderUtil(node)
{
if (node == null )
return ;
inorderUtil(node.left);
document.write(node.data + " " );
inorderUtil(node.right);
}
function insert(data)
{
this .root = this .insertRec( this .root, data);
}
function insertRec(node , data)
{
if (node == null ) {
this .root = new Node(data);
return this .root;
}
if (data <= node.data) {
node.left = this .insertRec(node.left, data);
}
else {
node.right = this .insertRec(node.right, data);
}
return node;
}
class Sum {
constructor(){
this .sum = 0;
}
}
function modifyBSTUtil(node, S)
{
if (node == null )
return ;
this .modifyBSTUtil(node.right, S);
S.sum = S.sum + node.data;
node.data = S.sum;
this .modifyBSTUtil(node.left, S);
}
function modifyBST(node)
{
var S = new Sum();
this .modifyBSTUtil(node, S);
}
insert(50);
insert(30);
insert(20);
insert(40);
insert(70);
insert(60);
insert(80);
modifyBST(root);
inorder();
</script>
|
Output350 330 300 260 210 150 80
Complexity Analysis:
- Time Complexity: O(n).
As this problem uses an in-order tree traversal technique - Auxiliary Space: O(1).
As no data structure has been used for storing values.
Approach 2: Recursive Inorder Traversal
In this approach, we traverse the BST in reverse inorder traversal, which gives us the nodes in descending order. While traversing, we maintain a variable sum that keeps track of the sum of all greater nodes than the current node. We add the sum to the current node’s value and update the sum to the new value. This way, we update all nodes with the sum of all greater nodes.
Initialize a variable sum to 0.
Traverse the given BST in reverse inorder (right, root, left) and for each node:
a. Add the node’s value to sum.
b. Replace the node’s value with sum.
Return the modified BST.
The reverse inorder traversal ensures that we visit the nodes in descending order, which allows us to calculate the sum of all greater values for each node. By keeping track of the running sum, we can easily update each node’s value with the sum of all greater values.
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
Node *left, *right;
};
Node* newNode( int data) {
Node* node = new Node;
node->data = data;
node->left = node->right = NULL;
return node;
}
void modifyBSTUtil(Node* root, int * sum) {
if (root == NULL) return ;
modifyBSTUtil(root->right, sum);
*sum = *sum + root->data;
root->data = *sum;
modifyBSTUtil(root->left, sum);
}
void modifyBST(Node* root) {
int sum = 0;
modifyBSTUtil(root, &sum);
}
void inorder(Node* root) {
if (root == NULL) return ;
inorder(root->left);
cout << root->data << " " ;
inorder(root->right);
}
int main() {
Node* root = newNode(50);
root->left = newNode(30);
root->right = newNode(70);
root->left->left = newNode(20);
root->left->right = newNode(40);
root->right->left = newNode(60);
root->right->right = newNode(80);
modifyBST(root);
inorder(root);
return 0;
}
|
Java
class Node {
int data;
Node left, right;
Node( int data) {
this .data = data;
left = right = null ;
}
}
public class Main{
static void modifyBSTUtil(Node root, int [] sum) {
if (root == null )
return ;
modifyBSTUtil(root.right, sum);
sum[ 0 ] = sum[ 0 ] + root.data;
root.data = sum[ 0 ];
modifyBSTUtil(root.left, sum);
}
static void modifyBST(Node root) {
int [] sum = new int [ 1 ];
modifyBSTUtil(root, sum);
}
static void inorder(Node root) {
if (root == null )
return ;
inorder(root.left);
System.out.print(root.data + " " );
inorder(root.right);
}
public static void main(String[] args) {
Node root = new Node( 50 );
root.left = new Node( 30 );
root.right = new Node( 70 );
root.left.left = new Node( 20 );
root.left.right = new Node( 40 );
root.right.left = new Node( 60 );
root.right.right = new Node( 80 );
modifyBST(root);
inorder(root);
}
}
|
Python3
class Node:
def __init__( self , data):
self .data = data
self .left = None
self .right = None
def newNode(data):
node = Node(data)
return node
def modifyBSTUtil(root, sum ):
if root is None :
return
modifyBSTUtil(root.right, sum )
sum [ 0 ] + = root.data
root.data = sum [ 0 ]
modifyBSTUtil(root.left, sum )
def modifyBST(root):
sum = [ 0 ]
modifyBSTUtil(root, sum )
def inorder(root):
if root is None :
return
inorder(root.left)
print (root.data, end = ' ' )
inorder(root.right)
if __name__ = = '__main__' :
root = newNode( 50 )
root.left = newNode( 30 )
root.right = newNode( 70 )
root.left.left = newNode( 20 )
root.left.right = newNode( 40 )
root.right.left = newNode( 60 )
root.right.right = newNode( 80 )
modifyBST(root)
inorder(root)
|
C#
using System;
public class Node {
public int data;
public Node left, right;
public Node( int data) {
this .data = data;
left = right = null ;
}
}
public class GFG {
static void ModifyBSTUtil(Node root, ref int sum) {
if (root == null )
return ;
ModifyBSTUtil(root.right, ref sum);
sum = sum + root.data;
root.data = sum;
ModifyBSTUtil(root.left, ref sum);
}
static void ModifyBST(Node root) {
int sum = 0;
ModifyBSTUtil(root, ref sum);
}
static void Inorder(Node root) {
if (root == null )
return ;
Inorder(root.left);
Console.Write(root.data + " " );
Inorder(root.right);
}
public static void Main( string [] args) {
Node root = new Node(50);
root.left = new Node(30);
root.right = new Node(70);
root.left.left = new Node(20);
root.left.right = new Node(40);
root.right.left = new Node(60);
root.right.right = new Node(80);
ModifyBST(root);
Inorder(root);
}
}
|
Javascript
class Node {
constructor(data) {
this .data = data;
this .left = this .right = null ;
}
}
function newNode(data) {
let node = new Node(data);
return node;
}
function modifyBSTUtil(root, sum) {
if (root == null ) return ;
modifyBSTUtil(root.right, sum);
sum[0] = sum[0] + root.data;
root.data = sum[0];
modifyBSTUtil(root.left, sum);
}
function modifyBST(root) {
let sum = [0];
modifyBSTUtil(root, sum);
}
function inorder(root) {
if (root == null ) return ;
inorder(root.left);
console.log(root.data + " " );
inorder(root.right);
}
let root = newNode(50);
root.left = newNode(30);
root.right = newNode(70);
root.left.left = newNode(20);
root.left.right = newNode(40);
root.right.left = newNode(60);
root.right.right = newNode(80);
modifyBST(root);
inorder(root);
|
Output350 330 300 260 210 150 80
Time Complexity: O(n), where n is the number of nodes in the BST.
Auxiliary Space: O(h), where h is the height of the BST.