题目描述:

二叉搜索树中的两个节点被错误地交换。

请在不改变其结构的情况下,恢复这棵树。

示例 1:

输入: [1,3,null,null,2]

1
/
3
\
2

输出: [3,1,null,null,2]

3
/
1
\
2
示例 2:

输入: [3,1,4,null,null,2]

3
/ \
1 4
/
2

输出: [2,1,4,null,null,3]

2
/ \
1 4
/
3

思想:按照中序遍历二叉树,查找两个违反由小到大的节点。
1、定义两个空指针p、q,p指向第一个错误节点,q指向第二个错误节点
2、第一个错误节点p指向前一个节点,第二个错误的节点指向后一个节点

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode *pre=NULL,*p=NULL,*q=NULL;
void inorder(TreeNode* &root,TreeNode* &pre,TreeNode* &p,TreeNode* &q){
if(root==NULL)
return ;
inorder(root->left,pre,p,q);
if(pre){
if(pre->val>root->val){//违反有小到大规则
if(p==NULL)//第一个错误的节点
p=pre;
q=root;//此时第二个节点暂时指向当前root节点
/*
这里包含两种情况:
1、确实可以查找到第二个违反规则的节点,q指向root(后一个节点)。如:321
2、找不到第二个节点,即错误节点是相邻的节点,则q指向root。如:1324
*/
}
}
pre=root;
inorder(root->right,pre,p,q);
}
void recoverTree(TreeNode* root) {
if(root==NULL)
return ;
inorder(root,pre,p,q);
swap(p->val,q->val);//树全部遍历完成后,交换p和q的值
}
};

LeetCode_99. 恢复二叉搜索树_中序遍历