6

Given a binary search tree, in which any two nodes are swapped. So we need to find those two nodes and swap them back(we need to swap the nodes, not the data)

I tried to do this by making an additional array which has the inorder traversal of the tree and also saves the pointer to each node. Then we just traverse the array and find the two nodes that are not in the sorted order, now these two nodes are searched in the tree and then swapped

So my question is how to solve this problem in O(1) space ?

Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
Aman Singhal
  • 835
  • 1
  • 11
  • 24
  • Refer [this](http://www.geeksforgeeks.org/fix-two-swapped-nodes-of-bst/). It actually makes use of just three more pointers. – user3004790 Jul 26 '14 at 15:14

3 Answers3

7

In order traversal on a BST gives you a traversal on the elements, ordered.
You can use an in-order traversal, find the two out of place elements (store them in two pointers) and swap them back.

This method is actually creating the array you described on the fly, without actually creating it.

Note that however, space consumption is not O(1), it is O(h) where h is the height of the tree, due to the stack trace. If the tree is balanced, it will be O(logn)

amit
  • 175,853
  • 27
  • 231
  • 333
  • if you create an array of all `n` elements from the tree, how do you end up with space complexity of `O(h)`? – Salvador Dali Mar 23 '16 at 09:59
  • @SalvadorDali `This method is actually creating the array you described on the fly, **without actually creating it.**` – amit Mar 23 '16 at 10:02
  • thank you for a fast answer, but I read it. And this magic combination of words is not really clear. Especially when it is obvious that one solution can be 'do inorder traversal and find swapped elements in the array'. Now I read your solution which tells the same, adding **without actually creating it**. So it somehow implies that I do not need to create it, but not how can I do this. Hope my point is clear. – Salvador Dali Mar 23 '16 at 10:15
  • @SalvadorDali When doing an in-order traversal, you get a *stream* of elements. At each point, you only need to store: Metadata (due to stack trace...), what is the last element, what is the current element. You never store the whole elements, just a small (and constant size) portion of them. (You do need O(h) space for the metadata though). – amit Mar 23 '16 at 10:32
0

Depending on the BST this can be done in O(1).

For instance, if the nodes of the tree have a pointer back to their parents you can use the implementation described in the nonRecrusiveInOrderTraversal section of the Wikipedia page for Tree_traversal.

As another possibility, if the BST is stored as a 1-dimensional array, instead of with pointers between nodes, you can simply walk over the array (and do the math to determine each node's parent and children).

While doing the traversal/walk, check to see if the current element is in the correct place.

If it isn't, then you can just see where in the tree it should be, and swap with the element in that location. (take some care for if the root is in the wrong place).

Xantix
  • 3,321
  • 1
  • 14
  • 28
0

We can modified the isBST() method as below to swap those 2 randomly swapped nodes and correct it.

/* Returns true if the given tree is a binary search tree
 (efficient version). */
int isBST(struct node* node)
{
  struct node *x = NULL;
  return(isBSTUtil(node, INT_MIN, INT_MAX,&x));
}

/* Returns true if the given tree is a BST and its
   values are >= min and <= max. */
int isBSTUtil(struct node* node, int min, int max, struct node **x)
{

  /* an empty tree is BST */
  if (node==NULL)
     return 1;

  /* false if this node violates the min/max constraint */
  if (node->data < min || node->data > max) {
     if (*x == NULL) {
        *x = node;//same the first incident where BST property is not followed.
     }
     else {
        //here we second node, so swap it with *x.
        int tmp = node->data;
        node->data = (*x)->data;
        (*x)->data = tmp;

     }
     //return 0;
     return 1;//have to return 1; as we are not checking here if tree is BST, as we know it is not BST, and we are correcting it.
  }
  /* otherwise check the subtrees recursively,
   tightening the min or max constraint */
  return
    isBSTUtil(node->left, min, node->data-1, x) &&  // Allow only distinct values
    isBSTUtil(node->right, node->data+1, max, x);  // Allow only distinct values
}
user1174114
  • 178
  • 1
  • 19