Two nodes of a BST are swapped, correct the BST

本文介绍了一种解决二叉搜索树中两个节点被错误交换的问题的方法。通过一次遍历找到被交换的节点并进行修正,实现了O(n)的时间复杂度。

Two nodes of a BST are swapped, correct the BST[转载]

Two of the nodes of a Binary Search Tree (BST) are swapped. Fix (or correct) the 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

The inorder traversal of a BST produces a sorted array. So a simple method is to store inorder traversal of the input tree in an auxiliary array. Sort the auxiliary array. Finally, insert the auxiilary array elements back to the BST, keeping the structure of the BST same. Time complexity of this method is O(nLogn) and auxiliary space needed is O(n).

We can solve this in O(n) time and with a single traversal of the given BST. Since 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. There are two cases that we need to handle:

1. The swapped nodes are not adjacent in the inorder traversal of the BST.

 For example, Nodes 5 and 25 are swapped in {3 5 7 8 10 15 20 25}. 
 The inorder traversal of the given tree is 3 25 7 8 10 15 20 5 

If we observe carefully, during inorder traversal, we find node 7 is smaller than the previous visited node 25. Here save the context of node 25 (previous node). Again, we find that node 5 is smaller than the previous node 20. This time, we save the context of node 5 ( current node ). Finally swap the two node’s values.

2. The swapped nodes are adjacent in the inorder traversal of BST.

  For example, Nodes 7 and 8 are swapped in {3 5 7 8 10 15 20 25}. 
  The inorder traversal of the given tree is 3 5 8 7 10 15 20 25 

Unlike case #1, here only one point exists where a node value is smaller than previous node value. e.g. node 7 is smaller than node 8.

How to Solve? We will maintain three pointers, first, middle and last. When we find the first point where current node value is smaller than previous node value, we update the first with the previous node & middle with the current node. When we find the second point where current node value is smaller than previous node value, we update the last with the current node. In case #2, we will never find the second point. So, last pointer will not be updated. After processing, if the last node value is null, then two swapped nodes of BST are adjacent.

Following is the implementation of the given code.

  1 // Two nodes in the BST's swapped, correct the BST.
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4  
  5 /* A binary tree node has data, pointer to left child
  6    and a pointer to right child */
  7 struct node
  8 {
  9     int data;
 10     struct node *left, *right;
 11 };
 12  
 13 // A utility function to swap two integers
 14 void swap( int* a, int* b )
 15 {
 16     int t = *a;
 17     *a = *b;
 18     *b = t;
 19 }
 20  
 21 /* Helper function that allocates a new node with the
 22    given data and NULL left and right pointers. */
 23 struct node* newNode(int data)
 24 {
 25     struct node* node = (struct node *)malloc(sizeof(struct node));
 26     node->data = data;
 27     node->left = NULL;
 28     node->right = NULL;
 29     return(node);
 30 }
 31  
 32 // This function does inorder traversal to find out the two swapped nodes.
 33 // It sets three pointers, first, middle and last.  If the swapped nodes are
 34 // adjacent to each other, then first and middle contain the resultant nodes
 35 // Else, first and last contain the resultant nodes
 36 void correctBSTUtil( struct node* root, struct node** first,
 37                      struct node** middle, struct node** last,
 38                      struct node** prev )
 39 {
 40     if( root )
 41     {
 42         // Recur for the left subtree
 43         correctBSTUtil( root->left, first, middle, last, prev );
 44  
 45         // If this node is smaller than the previous node, it's violating
 46         // the BST rule.
 47         if (*prev && root->data < (*prev)->data)
 48         {
 49             // If this is first violation, mark these two nodes as
 50             // 'first' and 'middle'
 51             if ( !*first )
 52             {
 53                 *first = *prev;
 54                 *middle = root;
 55             }
 56  
 57             // If this is second violation, mark this node as last
 58             else
 59                 *last = root;
 60         }
 61  
 62         // Mark this node as previous
 63         *prev = root;
 64  
 65         // Recur for the right subtree
 66         correctBSTUtil( root->right, first, middle, last, prev );
 67     }
 68 }
 69  
 70 // A function to fix a given BST where two nodes are swapped.  This
 71 // function uses correctBSTUtil() to find out two nodes and swaps the
 72 // nodes to fix the BST
 73 void correctBST( struct node* root )
 74 {
 75     // Initialize pointers needed for correctBSTUtil()
 76     struct node *first, *middle, *last, *prev;
 77     first = middle = last = prev = NULL;
 78  
 79     // Set the poiters to find out two nodes
 80     correctBSTUtil( root, &first, &middle, &last, &prev );
 81  
 82     // Fix (or correct) the tree
 83     if( first && last )
 84         swap( &(first->data), &(last->data) );
 85     else if( first && middle ) // Adjacent nodes swapped
 86         swap( &(first->data), &(middle->data) );
 87  
 88     // else nodes have not been swapped, passed tree is really BST.
 89 }
 90  
 91 /* A utility function to print Inoder traversal */
 92 void printInorder(struct node* node)
 93 {
 94     if (node == NULL)
 95         return;
 96     printInorder(node->left);
 97     printf("%d ", node->data);
 98     printInorder(node->right);
 99 }
100  
101 /* Driver program to test above functions*/
102 int main()
103 {
104     /*   6
105         /  \
106        10    2
107       / \   / \
108      1   3 7  12
109      10 and 2 are swapped
110     */
111  
112     struct node *root = newNode(6);
113     root->left        = newNode(10);
114     root->right       = newNode(2);
115     root->left->left  = newNode(1);
116     root->left->right = newNode(3);
117     root->right->right = newNode(12);
118     root->right->left = newNode(7);
119  
120     printf("Inorder Traversal of the original tree \n");
121     printInorder(root);
122  
123     correctBST(root);
124  
125     printf("\nInorder Traversal of the fixed tree \n");
126     printInorder(root);
127  
128     return 0;
129 }

 

转载于:https://www.cnblogs.com/harvyxu/p/7795499.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值