[LeetCode] 一个BST的两个节点的值被交换,要求修正这个BST

来源:互联网 发布:改键位软件 编辑:程序博客网 时间:2024/05/21 15:43

给你一个搜索二叉树,如下:

            6

          /     \

    10           2

    /   \        /    \

1      3    7      12

可以看到 10 和 2 的位置发生了交换。要求设计算法,回复原来的BST。

算法一:http://www.geeksforgeeks.org/fix-two-swapped-nodes-of-bst/
算法二:下面的算法是一个流传很广的算法,但是其实是错误的。首先给出算法,然后给出failure case。
算法二思路:可以借助 isValidBST 的思想,找出被交换的两个节点 。找到之后,把他们交换回去就可以了。
代码如下:
#include <stdio.h>#include <stdlib.h>#define INT_MIN -100#define INT_MAX 100 struct Node{    int key;   Node* left;  Node* right;    Node(int k, Node* l, Node* r): key(k), left(l), right(r){};};void correct_helper(Node* root, Node** p1, Node** p2, int min, int max) {if(root==NULL) return;else if(root->key < max && root->key > min) {correct_helper(root->left, p1, p2, min, root->key);correct_helper(root->right, p1, p2, root->key, max);}else {if(*p1){ *p2 = root; return; }// return after the second invalid node foundelse *p1 = root;}}void correct(Node* root) {Node** p1 = new Node*(NULL);Node** p2 = new Node*(NULL);correct_helper(root, p1, p2, -100, 100);int temp = (*p1)->key;(*p1)->key = (*p2)->key;(*p2)->key = temp;}int main(){Node* n1 = new Node(1, NULL, NULL);Node* n3 = new Node(3, NULL, NULL);Node* n7 = new Node(7, NULL, NULL);Node* n12 = new Node(12, NULL, NULL);Node* n10 = new Node(10, n1, n3);Node* n2 = new Node(2, n7, n12);Node* n6 = new Node(6, n10, n2);correct(n6);}
算法二成功的条件是,被交换到两个节点分别位于一个祖先节点的左右子树中。
如果被交换的两个节点的其中一个是另外一个的祖先,算法二就失败了。
下面的二叉树就是个例子:
          3
        /
       4
      /
    5
上面的二叉树中,3和5被交换。算法二会失败。