📜  交换了一个BST的两个节点,请更正BST。套装2

📅  最后修改于: 2021-04-29 18:32:02             🧑  作者: Mango

给定一个二进制搜索树,其中交换了二进制搜索树(BST)的两个节点。任务是修复(或纠正)BST。
注意:BST将没有重复项。
例子

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

方法:

  • 以有序方式遍历BST并将节点存储在向量中。
  • 然后,在创建该向量的副本之后对它进行排序。
  • 使用插入排序,因为在对数组进行几乎排序时,它可以最好和最快地工作。就像这个问题一样,只有两个元素会移位,因此此处的插入排序将在线性时间内工作。
  • 排序后,将排序后的向量与之前创建的向量的副本进行比较,从而找出一些错误节点,并通过在树中找到它们并进行交换来修复它们。

下面是上述方法的实现:

C++
// C++ implementation of the above approach
#include 
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& 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& 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 v;
  
    // Function call to insert
    // nodes into vector
    inorder(root, v);
  
    // create a copy of the vector
    vector 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;
}


Java
// Java implementation of the above approach
import java.util.ArrayList;
class GFG
{
 
    // A binary tree node has data, pointer
    // to left child and a pointer to right child
    static class node
    {
        int data;
        node left, right;
 
        public node(int x)
        {
            data = x;
            left = right = null;
        }
    };
 
    // Utility function for insertion sort
    static void insertionSort(ArrayList v, int n) {
        int i, key, j;
        for (i = 1; i < n; i++) {
            key = v.get(i);
            j = i - 1;
            while (j >= 0 && v.get(j) > key) {
                v.set(j + 1, v.get(i));
                j = j - 1;
            }
            v.set(j + 1, key);
        }
    }
 
    // Utility function to create a vector
    // with inorder traversal of a binary tree
    static void inorder(node root, ArrayList v) {
        // Base cases
        if (root == null)
            return;
 
        // Recurive call for left subtree
        inorder(root.left, v);
 
        // Insert node into vector
        v.add(root.data);
 
        // Recursive call for right subtree
        inorder(root.right, v);
    }
 
    // Function to exchange data
    // for incorrect nodes
    static void find(node root, int res, int res2)
    {
       
        // Base cases
        if (root == null) {
            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
    static node correctBST(node root)
    {
       
        // Vector to store the
        // inorder traversal of tree
        ArrayList v = new ArrayList<>();
 
        // Function call to insert
        // nodes into vector
        inorder(root, v);
 
        // create a copy of the vector
        ArrayList v1 = new ArrayList<>(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.get(i) != v1.get(i)) {
 
                // Find and exchange the
                // data of the two nodes
                find(root, v1.get(i), v.get(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
    static void printInorder(node node) {
        if (node == null)
            return;
        printInorder(node.left);
        System.out.printf("%d ", node.data);
        printInorder(node.right);
    }
 
  // Driver code
    public static void main(String[] args) {
 
        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.printf("Inorder Traversal of the");
        System.out.printf("original tree \n");
 
        printInorder(root);
 
        correctBST(root);
 
        System.out.printf("\nInorder Traversal of the");
        System.out.printf("fixed tree \n");
 
        printInorder(root);
 
    }
}
 
    // This code is contributed by sanjeev2552


C++
// C++ implementation of the
// above approach
 
#include 
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


Java
// 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


C#
// 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


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

时间复杂度: O(N)
辅助空间: O(N),其中N是二叉树中的节点数。

方法2:

要了解这一点,您需要首先了解Morris遍历Morris线程遍历。它利用叶节点的右/左指针在二叉树上实现O(1)空间遍历。

因此,通过这种方法,我们可以在O(n)时间和O(1)空间(即恒定空间)中解决此问题,只需遍历给定的BST。由于BST的有序遍历始终是一个有序数组,因此该问题可以简化为交换有序数组中两个元素的问题。

下面是上述方法的实现:

C++

// C++ implementation of the
// above approach
 
#include 
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

Java

// 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

C#

// 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
输出
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 

时间复杂度: O(N)
辅助空间: O(1)