Two nodes of a BST are swapped, correct the BST

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

Recommended: Please solve it on “PRACTICE” first, before moving on to the solution.

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 }
时间: 2024-10-17 16:54:12

Two nodes of a BST are swapped, correct the BST的相关文章

Leetcode-Recover BST

Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing its structure. Note: A solution using O(n) space is pretty straight forward. Could you devise a constant space solution? O(n) space solution: 1 /** 2

[算法专题] BST&amp;AVL

BST 以下BST的定义来自于Wikipedia: Binary Search Tree, is a node-based binary tree data structure which has the following properties: The left subtree of a node contains only nodes with keys less than the node's key. The right subtree of a node contains only

Recover BST

问题描述 Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing its structure. 解决思路 递归思路. 中序遍历的过程中,第一个违反顺序的节点一定是错误节点的其中一个:第二个违反顺序的节点的下一个节点是另外一个错误节点. 程序 public class RecoverBST { private TreeNode pre = null; p

71 Query Rank Min Max Successor of BST

[本文链接] http://www.cnblogs.com/hellogiser/p/query-min-max-successor-of-bst.html [代码] C++ Code 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283

[leetcode]98. Validate Binary Search Tree验证BST

Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as follows: The left subtree of a node contains only nodes with keys less than the node's key. The right subtree of a node contains only nodes with keys

【查找结构 2】二叉查找树 [BST]

当所有的静态查找结构添加和删除一个数据的时候,整个结构都需要重建.这对于常常需要在查找过程中动态改变数据而言,是灾难性的.因此人们就必须去寻找高效的动态查找结构,我们在这讨论一个非常常用的动态查找树——二叉查找树 . 二叉查找树的特点 下面的图就是两棵二叉查找树,我们可以总结一下他的特点: (1) 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值 (2) 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值(3) 它的左.右子树也分别为二叉查找树 我们中序遍历这两棵树发现一个

树和二叉树总结(三)—BST二叉排序树

二叉排序树的特点:中序遍历是递增的… 下面复习几个常用的操作: 1.如何向BST中插入一个节点 思路:用递归做... 首先,判断head是否为空,为空就是需要插的地方: 然后,判断head的data是不是和新Node一样,一样就是重复Node,不加 最后,若比当前head.data小,则放到插到左节点的树你,否则就插到右节点 public static Node insertBST(Node root, Node keyNode) { if (root== null) { //如果遇到空的地方,

BST二叉搜索树

1.二叉搜索树 (1).逼近折半查找的查找算法: (2).一般不允许出现重复数字,不然没法存储: (3).满足:左孩子数据 < 根结点数据 < 右孩子数据:根(父)结点比左孩子的大,比右孩子的小: (4)左子树和右子树也是二叉搜索树: 2.为什么叫二叉搜索树? 如果对一颗二叉搜索树进行中序遍历,可以按从小到大的顺序输出,此时又叫做二叉排序树. 如图: 3.搜索二叉树上的操作 全部用C++实现的. (1).之前学习二叉树,并没有说什么插入,删除操作,那是因为,没有规律而言,怎么进行操作呢?搜索二

Implement BST

1 import java.util.*; 2 3 //docs about generic version of class: https://docs.oracle.com/javase/tutorial/java/generics/types.html 4 public class myBST <T extends Comparable<T>>{ 5 6 //define tree node using a inner class 7 private class Node&l