We have discussed simple BST insert. How to insert in a tree where parent pointer needs to be maintained. Parent pointers are helpful to quickly find ancestors of a node, LCA of two nodes, successor of a node, etc.
In recursive calls of simple insertion, we return pointer of root of subtree created in a subtree. So the idea is to store this pointer for left and right subtrees. We set parent pointers of this returned pointers after the recursive calls. This makes sure that all parent pointers are set during insertion. Parent of root is set to NULL. We handle this by assigning parent as NULL by default to all newly allocated nodes.
Implementation:
// C++ program to demonstrate insert operation // in binary search tree with parent pointer #include<bits/stdc++.h> struct Node
{ int key;
struct Node *left, *right, *parent;
}; // A utility function to create a new BST Node struct Node *newNode( int item)
{ struct Node *temp = new Node;
temp->key = item;
temp->left = temp->right = NULL;
temp->parent = NULL;
return temp;
} // A utility function to do inorder traversal of BST void inorder( struct Node *root)
{ if (root != NULL)
{
inorder(root->left);
printf ( "Node : %d, " , root->key);
if (root->parent == NULL)
printf ( "Parent : NULL \n" );
else
printf ( "Parent : %d \n" , root->parent->key);
inorder(root->right);
}
} /* A utility function to insert a new Node with given key in BST */
struct Node* insert( struct Node* node, int key)
{ /* If the tree is empty, return a new Node */
if (node == NULL) return newNode(key);
/* Otherwise, recur down the tree */
if (key < node->key)
{
Node *lchild = insert(node->left, key);
node->left = lchild;
// Set parent of root of left subtree
lchild->parent = node;
}
else if (key > node->key)
{
Node *rchild = insert(node->right, key);
node->right = rchild;
// Set parent of root of right subtree
rchild->parent = node;
}
/* return the (unchanged) Node pointer */
return node;
} // Driver Program to test above functions int main()
{ /* Let us create following BST
50
/ \
30 70
/ \ / \
20 40 60 80 */
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);
// print inorder traversal of the BST
inorder(root);
return 0;
} |
// Java program to demonstrate insert operation // in binary search tree with parent pointer class GfG {
static class Node
{ int key;
Node left, right, parent;
} // A utility function to create a new BST Node static Node newNode( int item)
{ Node temp = new Node();
temp.key = item;
temp.left = null ;
temp.right = null ;
temp.parent = null ;
return temp;
} // A utility function to do inorder traversal of BST static void inorder(Node root)
{ if (root != null )
{
inorder(root.left);
System.out.print( "Node : " + root.key + " , " );
if (root.parent == null )
System.out.println( "Parent : NULL" );
else
System.out.println( "Parent : " + root.parent.key);
inorder(root.right);
}
} /* A utility function to insert a new Node with given key in BST */ static Node insert(Node node, int key)
{ /* If the tree is empty, return a new Node */
if (node == null ) return newNode(key);
/* Otherwise, recur down the tree */
if (key < node.key)
{
Node lchild = insert(node.left, key);
node.left = lchild;
// Set parent of root of left subtree
lchild.parent = node;
}
else if (key > node.key)
{
Node rchild = insert(node.right, key);
node.right = rchild;
// Set parent of root of right subtree
rchild.parent = node;
}
/* return the (unchanged) Node pointer */
return node;
} // Driver Program to test above functions public static void main(String[] args)
{ /* Let us create following BST
50
/ \
30 70
/ \ / \
20 40 60 80 */
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 );
// print iNorder traversal of the BST
inorder(root);
} } |
# Python3 program to demonstrate insert operation # in binary search tree with parent pointer # A utility function to create a new BST Node class newNode:
def __init__( self , item):
self .key = item
self .left = self .right = None
self .parent = None
# A utility function to do inorder # traversal of BST def inorder(root):
if root ! = None :
inorder(root.left)
print ( "Node :" , root.key, ", " , end = "")
if root.parent = = None :
print ( "Parent : NULL" )
else :
print ( "Parent : " , root.parent.key)
inorder(root.right)
# A utility function to insert a new # Node with given key in BST def insert(node, key):
# If the tree is empty, return a new Node
if node = = None :
return newNode(key)
# Otherwise, recur down the tree
if key < node.key:
lchild = insert(node.left, key)
node.left = lchild
# Set parent of root of left subtree
lchild.parent = node
elif key > node.key:
rchild = insert(node.right, key)
node.right = rchild
# Set parent of root of right subtree
rchild.parent = node
# return the (unchanged) Node pointer
return node
# Driver Code if __name__ = = '__main__' :
# Let us create following BST
# 50
# / \
# 30 70
# / \ / \
# 20 40 60 80
root = None
root = insert(root, 50 )
insert(root, 30 )
insert(root, 20 )
insert(root, 40 )
insert(root, 70 )
insert(root, 60 )
insert(root, 80 )
# print iNorder traversal of the BST
inorder(root)
# This code is contributed by PranchalK |
// C# program to demonstrate insert operation // in binary search tree with parent pointer using System;
class GfG
{ class Node
{
public int key;
public Node left, right, parent;
}
// A utility function to create a new BST Node
static Node newNode( int item)
{
Node temp = new Node();
temp.key = item;
temp.left = null ;
temp.right = null ;
temp.parent = null ;
return temp;
}
// A utility function to do
// inorder traversal of BST
static void inorder(Node root)
{
if (root != null )
{
inorder(root.left);
Console.Write( "Node : " + root.key + " , " );
if (root.parent == null )
Console.WriteLine( "Parent : NULL" );
else
Console.WriteLine( "Parent : " +
root.parent.key);
inorder(root.right);
}
}
/* A utility function to insert a new Node with
given key in BST */
static Node insert(Node node, int key)
{
/* If the tree is empty, return a new Node */
if (node == null ) return newNode(key);
/* Otherwise, recur down the tree */
if (key < node.key)
{
Node lchild = insert(node.left, key);
node.left = lchild;
// Set parent of root of left subtree
lchild.parent = node;
}
else if (key > node.key)
{
Node rchild = insert(node.right, key);
node.right = rchild;
// Set parent of root of right subtree
rchild.parent = node;
}
/* return the (unchanged) Node pointer */
return node;
}
// Driver code
public static void Main(String[] args)
{
/* Let us create following BST
50
/ \
30 70
/ \ / \
20 40 60 80 */
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);
// print iNorder traversal of the BST
inorder(root);
}
} // This code is contributed 29AjayKumar |
<script> // javascript program to demonstrate insert operation // in binary search tree with parent pointer class Node {
constructor() {
this .key = 0;
this .left = null ;
this .right = null ;
this .parent = null ;
}
}
// A utility function to create a new BST Node function newNode(item)
{ var temp = new Node();
temp.key = item;
temp.left = null ;
temp.right = null ;
temp.parent = null ;
return temp;
} // A utility function to do inorder traversal of BST function inorder(root)
{ if (root != null )
{
inorder(root.left);
document.write( "Node : " + root.key + " , " );
if (root.parent == null )
document.write( "Parent : NULL<br/>" );
else
document.write( "Parent : " + root.parent.key+ "<br/>" );
inorder(root.right);
}
} /* A utility function to insert a new Node with given key in BST */ function insert(node , key)
{ /* If the tree is empty, return a new Node */
if (node == null ) return newNode(key);
/* Otherwise, recur down the tree */
if (key < node.key)
{
var lchild = insert(node.left, key);
node.left = lchild;
// Set parent of root of left subtree
lchild.parent = node;
}
else if (key > node.key)
{
var rchild = insert(node.right, key);
node.right = rchild;
// Set parent of root of right subtree
rchild.parent = node;
}
/* return the (unchanged) Node pointer */
return node;
} // Driver Program to test above functions /* Let us create following BST
50
/ \
30 70
/ \ / \
20 40 60 80 */
var root = null ;
root = insert(root, 50);
insert(root, 30);
insert(root, 20);
insert(root, 40);
insert(root, 70);
insert(root, 60);
insert(root, 80);
// print iNorder traversal of the BST
inorder(root);
// This code contributed by umadevi9616 </script> |
Node : 20, Parent : 30 Node : 30, Parent : 50 Node : 40, Parent : 30 Node : 50, Parent : NULL Node : 60, Parent : 70 Node : 70, Parent : 50 Node : 80, Parent : 70
Time Complexity: The time complexity of insertion in a binary search tree (BST) depends on the height of the tree. In the worst-case scenario, the height of the tree can be equal to the number of nodes in the tree, which leads to a time complexity of O(n). However, if the tree is balanced, the height is equal to log n, where n is the number of nodes in the tree. Therefore, the time complexity of the insert operation in a balanced BST is O(log n).
Space Complexity: The space complexity of the insert operation in a BST is O(h), where h is the height of the tree. In the worst-case scenario, the height of the tree is equal to the number of nodes in the tree, leading to a space complexity of O(n). However, if the tree is balanced, the height is equal to log n, leading to a space complexity of O(log n).
Exercise:
How to maintain parent pointer during deletion.