Tuesday, November 6, 2012

Recover Binary Search Tree

Problem:
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?

Solution:
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    void recoverTree(TreeNode *root) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        TreeNode *firstOdd=NULL, *secondOdd=NULL;
        int i, c;
        vector<TreeNode *> inorderTraversal = inorder(root);
        for (i=0; i <inorderTraversal.size() - 1; i++) {
            if (inorderTraversal[i]->val > inorderTraversal[i+1]->val) {
                firstOdd = inorderTraversal[i];
                break;
            }
        }
        for (i=inorderTraversal.size() - 1; i > 0; i--) {
            if (inorderTraversal[i]->val < inorderTraversal[i - 1]->val) {
                secondOdd = inorderTraversal[i];
                break;
            }
        }
        // Swapping the odds.
        if (firstOdd != NULL && secondOdd != NULL) {
            c = firstOdd->val;
            firstOdd->val = secondOdd->val;
            secondOdd->val = c;
        }
    }
   
   // Iterative Inorder
    vector<TreeNode *> inorder(TreeNode *root) {
        vector<TreeNode*> inorder_ans;
        stack<TreeNode*> instack;
        TreeNode *popedNode=NULL, *node = root;
  
        while (1) {
           while (node!= NULL) {
              instack.push(node);
              node = node->left;
           }
          
           popedNode = instack.top();
           instack.pop();
           inorder_ans.push_back(popedNode);

           if (popedNode->right != NULL)
               node = popedNode->right;
           else if (instack.empty())
               break;
        }
        return inorder_ans;
    }
};

=================================================
Another efficient Iterative Inorder traversal of Binary search tree. Following code is taken from Link

bool done;
   binary_tree_node<Item> *root_ptr, *cursor;
   stack<binary_tree_node<Item> *> s;

   cursor = root_ptr;             //set cursor to root of binary tree
   done = false;

   while (!done)
   {
      if(cursor != NULL)
      {
         s.push(cursor);          //place pointer to node on the stack
                                  //before traversing the node's left subtree
         cursor = cursor->left(); //traverse the left subtree
      }
      else                        //backtrack from the empty subtree and
                                  //visit the node at the top of the stack;
                                  //however, if the stack is empty, you are
                                  //done
      {
         if (!s.empty())
         {
             cursor = s.top();
      s.pop();
             cout << cursor->data();
             cursor = cursor->right();
         }
         else
             done = true;
      }
   }

No comments:

Post a Comment