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

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

            6

          /     \

    10           2

    /   \        /    \

1      3    7      12

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

算法一: http://www.geeksforgeeks.org/fix-two-swapped-nodes-of-bst/
算法二:下面的算法是一个流传很广的算法,但是其实是错误的。首先给出算法,然后给出failure case。
算法二思路:可以借助 isValidBST 的思想,找出被交换的两个节点 。找到之后,把他们交换回去就可以了。
代码如下:
#include 
#include 

#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 found
		else 	*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被交换。算法二会失败。
           

你可能感兴趣的:(树,leetcode)