Two nodes of a BST are swapped, correct the BST | Set-2

Given a Binary Search Tree with two of the nodes of the Binary Search Tree (BST) swapped. The task is to fix (or correct) the BST.
Note: The BST will not have duplicates.
Examples

Input Tree:
         10
        /  \
       5    8
      / \
     2   20

In the above tree, nodes 20 and 8 must be swapped to fix the tree.  
Following is the output tree
         10
        /  \
       5    20
      / \
     2   8




Approach: 

Below is the implementation of the above approach: 

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the above approach
#include <bits/stdc++.h>
using namespace std;
  
// A binary tree node has data, pointer
// to left child and a pointer to right child
struct node {
    int data;
    struct node *left, *right;
    node(int x)
    {
        data = x;
        left = right = NULL;
    }
};
  
// Utility function for insertion sort
void insertionSort(vector<int>& v, int n)
{
    int i, key, j;
    for (i = 1; i < n; i++) {
        key = v[i];
        j = i - 1;
        while (j >= 0 && v[j] > key) {
            v[j + 1] = v[j];
            j = j - 1;
        }
        v[j + 1] = key;
    }
}
  
// Utility function to create a vector
// with inorder traversal of a binary tree
void inorder(node* root, vector<int>& v)
{
    // Base cases
    if (!root)
        return;
  
    // Recurive call for left subtree
    inorder(root->left, v);
  
    // Insert node into vector
    v.push_back(root->data);
  
    // Recursive call for right subtree
    inorder(root->right, v);
}
  
// Function to exchange data
// for incorrect nodes
void find(node* root, int res, int res2)
{
    // Base cases
    if (!root) {
        return;
    }
  
    // Recurive call to find
    // the node in left subtree
    find(root->left, res, res2);
  
    // Check if current node
    // is incorrect and exchange
    if (root->data == res) {
        root->data = res2;
    }
    else if (root->data == res2) {
        root->data = res;
    }
  
    // Recurive call to find
    // the node in right subtree
    find(root->right, res, res2);
}
  
// Primary function to fix the two nodes
struct node* correctBST(struct node* root)
{
    // Vector to store the
    // inorder traversal of tree
    vector<int> v;
  
    // Function call to insert
    // nodes into vector
    inorder(root, v);
  
    // create a copy of the vector
    vector<int> v1 = v;
  
    // Sort the original vector thereby
    // making it a valid BST's inorder
    insertionSort(v, v.size());
  
    // Traverse through both vectors and
    // compare misplaced values in original BST
    for (int i = 0; i < v.size(); i++) {
 
        // Find the mismatched values
        // and interchange them
        if (v[i] != v1[i]) {
 
            // Find and exchange the
            // data of the two nodes
            find(root, v1[i], v[i]);
  
            // As it given only two values are
            // wrong we don't need to check further
            break;
        }
    }
  
    // Return the root of corrected BST
    return root;
}
 
// A utility function to
// print Inoder traversal
void printInorder(struct node* node)
{
    if (node == NULL)
        return;
    printInorder(node->left);
    printf("%d ", node->data);
    printInorder(node->right);
}
  
int main()
{
    struct node* root = new node(6);
    root->left = new node(10);
    root->right = new node(2);
    root->left->left = new node(1);
    root->left->right = new node(3);
    root->right->right = new node(12);
    root->right->left = new node(7);
  
    printf("Inorder Traversal of the");
    printf("original tree \n");
 
    printInorder(root);
  
    correctBST(root);
  
    printf("\nInorder Traversal of the");
    printf("fixed tree \n");
 
    printInorder(root);
  
    return 0;
}
chevron_right

Output
Inorder Traversal of theoriginal tree 
1 10 3 6 7 2 12 
Inorder Traversal of thefixed tree 
1 2 3 6 7 10 12 



Time Complexity: O(N) 
Auxiliary Space: O(N), where N is the number of nodes in the Binary Tree.



Method 2:

To understand this, you need to first understand Morris Traversal or Morris Threading Traversal. It makes use of leaf nodes’ right/left pointer to achieve O(1) space Traversal on a Binary Tree.

So, in this approach, we can solve this in O(n) time and O(1) space i.e constant space, with a single traversal of the given BST. Since the inorder traversal of BST is always a sorted array, the problem can be reduced to a problem where two elements of a sorted array are swapped.

Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the
// above approach
 
#include <bits/stdc++.h>
using namespace std ;
 
/* A binary tree node has data,
pointer to left child
and a pointer to right child */
struct node
{
    int data;
    struct node *left, *right;
};
 
// A utility function to swap two integers
void swap( int* a, int* b )
{
    int t = *a;
    *a = *b;
    *b = t;
}
 
/* Helper function that allocates
a new node with the
given data and NULL left and right pointers. */
struct node* newNode(int data)
{
    struct node* node = (struct node *)
            malloc(sizeof(struct node));
    node->data = data;
    node->left = NULL;
    node->right = NULL;
    return(node);
}
 
// Function for inorder traversal using
// Morris Traversal
void MorrisTraversal(struct node* root,
                     struct node* &first,
                     struct node* &last,
                     struct node* &prev )
{
       // Current node
      struct  node* curr = root;
     
        while(curr != NULL)
        {
            if(curr->left==NULL)
            {
               
                // If this node is smaller than
                // the previous node, it's 
                // violating the BST rule.
                if(first == NULL && prev != NULL &&
                   prev->data > curr->data)
                {
                    // If this is first violation,
                    // mark these two nodes as
                    // 'first' and 'last'
                    first = prev;
                    last = curr;
                }
                 
                if(first != NULL &&
                   prev->data > curr->data)
                {
                  // If this is second violation,         
                  // mark this node as last
                    last = curr;
                }
                prev = curr;
                 
                curr = curr->right;
            }
            else
            {
                  /* Find the inorder predecessor of current */
                 struct   node*  pre = curr->left;
                while(pre->right!=NULL && pre->right!=curr)
                {
                    pre = pre->right;
                }
                 
                /* Make current as right child of
                its inorder predecessor */
                if(pre->right==NULL)
                {
                    pre->right = curr;
                    curr = curr->left;
                }
                else
                {
                    // If this node is smaller than
                    // the previous node, it's 
                    // violating the BST rule.
                    if(first == NULL && prev!=NULL &&
                       prev->data > curr->data)
                    {
                          // If this is first violation,
                        // mark these two nodes as
                        // 'first' and 'last'
                        first = prev;
                        last = curr;
                    }
 
                    if(first != NULL &&
                       prev->data > curr->data)
                    {
                          // If this is second violation,
                           // mark this node as last
                        last = curr;
                    }
                    prev = curr;
                   
                      /* Revert the changes made in the
                    'if' part to restore the 
                    original tree i.e., fix the
                    right child of predecessor*/
                    pre->right = NULL;
                    curr = curr->right;
                }
            }
        }
    }
 
// A function to fix a given BST
// where two nodes are swapped. This
// function uses correctBSTUtil()
// to find out two nodes and swaps the
// nodes to fix the BST
void correctBST( struct node* root )
{
    // Initialize pointers needed
    // for correctBSTUtil()
    struct node* first =NULL ;
    struct node* last = NULL ;
    struct node* prev =NULL ;
 
    // Set the poiters to find out two nodes
    MorrisTraversal( root ,first ,last , prev);
 
    // Fix (or correct) the tree
    swap( &(first->data), &(last->data) );
     
 
    // else nodes have not been swapped,
    // passed tree is really BST.
}
 
/* A utility function to print Inoder traversal */
void printInorder(struct node* node)
{
    if (node == NULL)
        return;
    printInorder(node->left);
    printf("%d ", node->data);
    printInorder(node->right);
}
 
/* Driver Code */
int main()
{
    /*   6
        / \
       10  2
      / \ / \
     1  3 7 12
    10 and 2 are swapped
    */
 
    struct node *root = newNode(6);
    root->left     = newNode(10);
    root->right     = newNode(2);
    root->left->left = newNode(1);
    root->left->right = newNode(3);
    root->right->right = newNode(12);
    root->right->left = newNode(7);
 
    printf("Inorder Traversal of the original tree \n");
    printInorder(root);
 
    correctBST(root);
 
    printf("\nInorder Traversal of the fixed tree \n");
    printInorder(root);
 
    return 0;
}
// This code is contributed by
// Sagara Jangra and Naresh Saharan
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to correct the BST 
// if two nodes are swapped
import java.util.*;
import java.lang.*;
import java.io.*;
   
class Node {
   
    int data;
    Node left, right;
   
    Node(int d) {
        data = d;
        left = right = null;
    }
}
 
class BinaryTree {
   
       Node first, last, prev;
       
    // This function does inorder traversal
    // Using Morris Traversal to find out the two
      // swapped nodes.
    void MorrisTraversal( Node root)
    {
       // current node
        Node curr = root;
        Node pre = null;
        while(curr != null)
        {
            if(curr.left==null)
            {
               
              // If this node is smaller than
              // the previous node, it's 
              // violating the BST rule.
                 
                if(first == null && prev != null &&
                   prev.data > curr.data)
                {
                      // If this is first violation,
                    // mark these two nodes as
                    // 'first' and 'last'
                    first = prev;
                    last = curr;
                }
                 
                if(first != null &&
                   prev.data > curr.data)
                {
                  // If this is second violation,         
                  // mark this node as last
                    last = curr;
                }
                prev = curr;
                 
                curr = curr.right;
            }
            else
            {
                  /* Find the inorder predecessor of current */
                pre = curr.left;
                while(pre.right!=null &&
                      pre.right!=curr)
                {
                    pre = pre.right;
                }
                 
                // Make current as right child of
                // its inorder predecessor */
                if(pre.right==null)
                {
                    pre.right = curr;
                    curr = curr.left;
                }
                else
                {
                    // If this node is smaller than
                    // the previous node, it's 
                    // violating the BST rule.
                    if(first == null && prev!=null &&
                       prev.data > curr.data)
                    {
                          // If this is first violation,
                        // mark these two nodes as
                        // 'first' and 'last'
                        first = prev;
                        last = curr;
                    }
 
                    if(first != null &&
                       prev.data > curr.data)
                    {
                          // If this is second violation,
                           // mark this node as last
                        last = curr;
                    }
                    prev = curr;
                   
                      /* Revert the changes made in the
                    'if' part to restore the 
                    original tree i.e., fix the
                    right child of predecessor*/
                    pre.right = null;
                    curr = curr.right;
                }
            }
        }
    }
   
       
      // A function to fix a given BST where 
    // two nodes are swapped. This function 
    // uses correctBSTUtil() to find out 
    // two nodes and swaps the nodes to 
    // fix the BST
    void correctBST( Node root )
    {
        // Initialize pointers needed 
        // for correctBSTUtil()
        first = last = prev = null;
   
        // Set the poiters to find out 
        // two nodes
        MorrisTraversal( root );
   
        // Fix (or correct) the tree
          int temp = first.data;
        first.data = last.data;
          last.data = temp; 
    }
   
   
       /* A utility function to print 
     Inoder traversal */
    void printInorder(Node node)
    {
        if (node == null)
            return;
        printInorder(node.left);
        System.out.print(" " + node.data);
        printInorder(node.right);
    }
   
    // Driver Code
    public static void main (String[] args) 
    {
        /*   6
            / \
           10  2
          / \ / \
         1  3 7 12
           
        10 and 2 are swapped
        */
   
        Node root = new Node(6);
        root.left = new Node(10);
        root.right = new Node(2);
        root.left.left = new Node(1);
        root.left.right = new Node(3);
        root.right.right = new Node(12);
        root.right.left = new Node(7);
   
        System.out.println("Inorder Traversal"+
                        " of the original tree");
        BinaryTree tree = new BinaryTree();
        tree.printInorder(root);
   
        tree.correctBST(root);
   
        System.out.println("\nInorder Traversal"+
                          " of the fixed tree");
        tree.printInorder(root);
    }
}
// This code is contributed by
// Naresh Saharan and Sagara Jangra
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to correct the BST 
// if two nodes are swapped
using System;
public
 
 
 class Node {
   
    public
 
 
 int data;
   public
 
 
  Node left, right;
   
    public Node(int d) {
        data = d;
        left = right = null;
    }
}
 
public class GFG {
   
       Node first, last, prev;
       
    // This function does inorder traversal
    // Using Morris Traversal to find out the two
      // swapped nodes.
    void MorrisTraversal( Node root)
    {
       // current node
        Node curr = root;
        Node pre = null;
        while(curr != null)
        {
            if(curr.left==null)
            {
               
              // If this node is smaller than
              // the previous node, it's 
              // violating the BST rule.
                 
                if(first == null && prev != null &&
                   prev.data > curr.data)
                {
                      // If this is first violation,
                    // mark these two nodes as
                    // 'first' and 'last'
                    first = prev;
                    last = curr;
                }
                 
                if(first != null &&
                   prev.data > curr.data)
                {
                  // If this is second violation,         
                  // mark this node as last
                    last = curr;
                }
                prev = curr;
                 
                curr = curr.right;
            }
            else
            {
                  /* Find the inorder predecessor of current */
                pre = curr.left;
                while(pre.right!=null &&
                      pre.right!=curr)
                {
                    pre = pre.right;
                }
                 
                // Make current as right child of
                // its inorder predecessor */
                if(pre.right==null)
                {
                    pre.right = curr;
                    curr = curr.left;
                }
                else
                {
                    // If this node is smaller than
                    // the previous node, it's 
                    // violating the BST rule.
                    if(first == null && prev!=null &&
                       prev.data > curr.data)
                    {
                          // If this is first violation,
                        // mark these two nodes as
                        // 'first' and 'last'
                        first = prev;
                        last = curr;
                    }
 
                    if(first != null &&
                       prev.data > curr.data)
                    {
                          // If this is second violation,
                           // mark this node as last
                        last = curr;
                    }
                    prev = curr;
                   
                      /* Revert the changes made in the
                    'if' part to restore the 
                    original tree i.e., fix the
                    right child of predecessor*/
                    pre.right = null;
                    curr = curr.right;
                }
            }
        }
    }
   
       
      // A function to fix a given BST where 
    // two nodes are swapped. This function 
    // uses correctBSTUtil() to find out 
    // two nodes and swaps the nodes to 
    // fix the BST
    void correctBST( Node root )
    {
        // Initialize pointers needed 
        // for correctBSTUtil()
        first = last = prev = null;
   
        // Set the poiters to find out 
        // two nodes
        MorrisTraversal( root );
   
        // Fix (or correct) the tree
          int temp = first.data;
        first.data = last.data;
          last.data = temp; 
    }
   
   
       /* A utility function to print 
     Inoder traversal */
    void printInorder(Node node)
    {
        if (node == null)
            return;
        printInorder(node.left);
        Console.Write(" " + node.data);
        printInorder(node.right);
    }
   
    // Driver Code
    public static void Main(String[] args) 
    {
        /*   6
            / \
           10  2
          / \ / \
         1  3 7 12
           
        10 and 2 are swapped
        */
   
        Node root = new Node(6);
        root.left = new Node(10);
        root.right = new Node(2);
        root.left.left = new Node(1);
        root.left.right = new Node(3);
        root.right.right = new Node(12);
        root.right.left = new Node(7);
   
        Console.WriteLine("Inorder Traversal"+
                        " of the original tree");
        GFG tree = new GFG();
        tree.printInorder(root);
   
        tree.correctBST(root);
   
        Console.WriteLine("\nInorder Traversal"+
                          " of the fixed tree");
        tree.printInorder(root);
    }
}
// This code contributed by gauravrajput1
chevron_right

Output
Inorder Traversal of the original tree 
1 10 3 6 7 2 12 
Inorder Traversal of the fixed tree 
1 2 3 6 7 10 12 



Time Complexity: O(N)
Auxiliary Space: O(1)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.





Check out this Author's contributed articles.

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.



Article Tags :