Pre-Order Successor of all nodes in Binary Search Tree

Consider a BST(Binary Search Tree) where duplicates are not allowed.

Given a key present in the BST. The task is to find its pre-order successor in this BST i.e. the task is to find a key that comes next to the given key if we apply a pre-order traversal on given BST.

Example:
Insert the following keys in a BST in the same order: 51, 39, 31, 54, 92, 42, 21, 10, 26, 52, 36, 47, 82, 5, 62.

You will end up with a BST as shown below:
Binary Search Tree formed after inserting the given data.

Pre-Order Traversal : 51 39 31 21 10 5 26 36 42 47 54 52 92 82 62

=====================================
Key       Pre-Order Successor
=====================================
51        39
39        31
31        21
21        10 
10        5
5         26
26        36
36        42
42        47
47        54
52        92
92        82
82        62
62        Do Not Exist.

Simple Approach: A simple and easy way to solve this problem is to apply pre-order traversal on given BST and store the keys of BST in an array. Next, search for the given key in array. If it exists then its next key(which may not necessarily exist) is its pre-order successor. If given key does not exist in the array that means given key does not exist in BST and hence there cannot be any pre-order successor for this key.

But this algorithm has a time-complexity of O(n). And space complexity of O(n) and hence it is not a good way to approach for this problem.

Efficient Approach: An efficient way to approach this problem is based on the following observations:

  • Search for a node in BST that contains the given key.
    • If it does not exist in BST then there cannot be any pre-order successor for this key.
    • If it exists in BST then there can be a pre-order successor for this key. Note that it is not necessary that if a key exists then it has a pre-order successor. It depends on the position of a given key in BST
  • If node containing the given key has a left child then its left child is its pre-order successor.
  • If node containing the given has a right but not left child then its right child is its pre-order successor.
  • If node containing the given key is a leaf then you have to search for its nearest ancestor that has a right child and key of this ancestor is greater than the given key i.e. you have to search for its nearest ancestor in left subtree of which the given key exist. Further two cases are there:
    • Such an ancestor exist, if so then the right child of this ancestor is the pre-order successor of the given key.
    • Such an ancestor do not exist, if so then there is no pre-order successor for the given key.

Below is the implementation of the above approach :

filter_none

edit
close

play_arrow

link
brightness_4
code

// C program to find pre-Order successor 
// of a node in Binary Search Tree
#include<stdio.h>
#include<stdlib.h>
  
// Declare a structure 
struct Node{
    // Key to be stored in BST
    int key; 
  
    // Pointer to left child
    struct Node *left;
  
    // Pointer to the right child
    struct Node *right;
      
    // Pointer to parent
    struct Node *parent;
};
  
// This function inserts node in BST
struct Node* insert(int key, struct Node *root, 
                                   struct Node *parent)
{
      
    // If root is NULL, insert key here
    if(!root)
    {
        // Allocate memory dynamically
        struct Node *node = (struct Node*)malloc(sizeof(struct Node));
  
        // Validate malloc call
        if(node)
        {
            // Populate the object pointer to by 
            // pointer named node
            node->key = key;
            node->left = node->right = NULL;
            node->parent = parent;
  
            // Return newly created node
            return node;
              
        
        else
            // Malloc was not successful to satisfy our request, 
            // given an appropriate message to the user
            printf("Could not allocate memory.");
          
    
      
    // If this is a duplicate key then give a message to user
    else if(key == root->key)
        printf("Duplicates are not allowed in BST.");
      
    // If the key to be inserted is greater than the root's 
    // key then it will go to the right subtree of 
    // the tree with current root
    else if(key > root->key)
        root->right = insert(key, root->right,root);
      
    // If the key to be inserted is smaller than the 
    // root's key then it will go to a left subtree of 
    // the tree with current root
    else
        root->left = insert(key, root->left, root);
      
    // Return the root
    return root;
}
  
// This function searched for a given key in BST
struct Node* search(int key, struct Node *root)
{
    // Since the root is empty and hence key
    // does not exist in BST
    if(!root)
        return NULL; 
      
    // Current root contains the given key, 
    // so return current root
    else if( key == root->key)
        return root; 
      
    // Key is greater than the root's key and therefore 
    // we will search for this key in the right subtree of 
    // tree with root as current root because of all of the keys 
    // which are greater than the root's key exist in the right subtree    
    else if(key > root->key)
        return search(key, root->right);
      
    // Key is smaller than the root's key and therefore we will 
    // search for this key in the left subtree of the tree with
    // root as the current root because of all of the keys which are 
    // smaller than the root's key exists in the left subtree
    // search tree in the left subtree
    else
        return search(key, root->left); 
      
}
  
// This function returns the node that contains the
// pre-order successor for the given key
struct Node* preOrderSuccessor(int key, struct Node *root){
  
    // Search for a node in BST that contains the given key
    struct Node *node = search(key, root);
  
    // There is no node in BST that contains the given key, 
    // give an appropriate message to user
    if(!node){
        printf("%d do not exists in BST.\n", key);
        return NULL;
    }
  
  
    // There exist a node in BST that contains the given key
    // Apply our observations
    if(node->left)
        // If left child of the node that contains the
        // given key exist then it is the pre-order 
        // successor for the given key
        return node->left;
  
    else if(node->right)
        // If right but not left child of node that contains 
        // the given key exist then it is the pre-order 
        // successor for the given key
        return node->right;
  
    else 
    {
        // Node containing the key has neither left nor right child 
        // which means that it is leaf node. In this case we will search 
        // for its nearest ancestor with right child which has a key 
        // greater than the given key
  
        // Since node is a leaf node so its parent is guaranteed to exist
        struct Node *temp = node->parent;
  
        // Search for nearest ancestor with right child that has 
        // key greater than the given key
        while(temp){
            if(key < temp->key && temp->right)
                break;
            temp = temp->parent;
        }
  
        // If such an ancestor exist then right child of this ancestor 
        // is the pre-order successor for the given otherwise there 
        // do not exist any pre-order successor for the given key
        return temp ? temp->right : NULL;
    }
}
  
// This function traverse the BST in pre-order fashion
void preOrder(struct Node *root)
{
    if(root)
    {
        // First visit the root
        printf("%d ", root->key);
          
        // Next visit its left subtree
        preOrder(root->left);
          
        // Finally visit its right subtree
        preOrder(root->right);
    }
}
  
// Driver code
int main()
{
    // Declares a root for our BST
    struct Node *ROOT = NULL;
  
    // We will create 15 random integers in 
    // range 0-99 to populate our BST
    int a[] = {51, 39, 31, 54, 92, 42, 21, 10, 
                          26, 52, 36, 47, 82, 5, 62};
  
    int n = sizeof(a) / sizeof(a[0]);
      
    // Insert all elements into BST
    for(int i = 0 ; i < n; i++)
    {
        // Insert the generated number in BST
        printf("Inserting %2d.....", a[i]);
          
        ROOT = insert(a[i], ROOT, NULL);
        printf("Finished Insertion.\n");
    }
  
    // Apply pre-order traversal on BST
    printf("\nPre-Order Traversal : ");
    preOrder(ROOT);
  
    // Display pre-order Successors for all of the keys in BST
    printf("\n=====================================");
    printf("\n%-10s%s\n", "Key", "Pre-Order Successor");
    printf("=====================================\n");
  
    // This stores the pre-order successor for a given key
    struct Node *successor = NULL;
  
    // Iterate through all of the elements inserted
    // in BST to get their pre-order successor
    for(int i = 0 ; i < n; ++i)
    {
        // Get the pre-order successor for the given key
        successor = preOrderSuccessor(a[i], ROOT);
  
        if(successor)
            // Successor is not NULL and hence it contains 
            // the pre-order successor for given key
            printf("%-10d%d\n", a[i], successor->key);
        else
            // Successor is NULL and hence given key do 
            // not have a pre-order successor
            printf("%-10dDo Not Exist.\n", a[i]);
    }
  
    return 0;
}

chevron_right


Output:

Inserting 51.....Finished Insertion.
Inserting 39.....Finished Insertion.
Inserting 31.....Finished Insertion.
Inserting 54.....Finished Insertion.
Inserting 92.....Finished Insertion.
Inserting 42.....Finished Insertion.
Inserting 21.....Finished Insertion.
Inserting 10.....Finished Insertion.
Inserting 26.....Finished Insertion.
Inserting 52.....Finished Insertion.
Inserting 36.....Finished Insertion.
Inserting 47.....Finished Insertion.
Inserting 82.....Finished Insertion.
Inserting  5.....Finished Insertion.
Inserting 62.....Finished Insertion.

Pre-Order Traversal : 51 39 31 21 10 5 26 36 42 47 54 52 92 82 62 
=====================================
Key       Pre-Order Successor
=====================================
51        39
39        31
31        21
54        52
92        82
42        47
21        10
10        5
26        36
52        92
36        42
47        54
82        62
5         26
62        Do Not Exist.


My Personal Notes arrow_drop_up

Java Developer in love with Full Stack Development panchalprogrammingacademy dot herokuapp dot com shubhampanchal9773 at gmail dot com

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.