问题:给出一个有问题的二叉查找树,其中有一对儿结点上的数字弄反了。要求把它俩找出来并恢复到正常的二叉查找树。
思路:正常的二叉查找树,中序遍历应该是递增序列。现在有一对数被交换了。那么中序序列中必定先遇到一个比其右边的数要大的数,然后再遇到一个比起左边的数小的数。
这两个数就是应该被交换回来的数。
比如交换两个不相邻的数 1 2 3 4 5,交换成 1 4 3 2 5,会发现两个降序:4到3为降序,3到2为降序。
比如交换两个相邻的数 1 2 3 4 5,交换成1 3 2 4 5,会发现一个降序:3降到2。
因此可能有两种情况。
代码:使用全局变量保存递归过程中发现的降序。
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<TreeNode *> rem;
void recoverTree(TreeNode *root) {
if(root == NULL)
return;
TreeNode *last = NULL;
find(root, last);
if(rem.size() == 4)//交换的数不相邻
{
swap(rem[0]->val, rem[3]->val);
}
else //交换的数相邻
{
swap(rem[0]->val, rem[1]->val);
}
}
//last参数保存中序遍历的上一个结点
void find(TreeNode* root, TreeNode* &last)
{
if(root->left != NULL)
find(root->left, last);
if(last != NULL && last->val > root->val)
{
rem.push_back(last);
rem.push_back(root);
}
last = root;//更新last
if(root->right != NULL)
find(root->right, last);
}
void swap(int &a, int &b)
{
int tmp;
tmp = a;
a = b;
b = tmp;
}
};