题目大意:一个二叉树搜索树中的有两个节点放错了位置,请将树恢复
分析:dfs。二叉搜索树满足中序遍历得到升序序列,如果有节点放反了就会出现逆序情况,例如原序列123456,如果2、5反了就是153426,出现两个逆序对,我们要找到交换的两个节点即为第一个逆序对的第一个结点和第二个逆序对的第二个节点。所以dfs遍历时我们用pre指针维护当前节点的前一个结点,然后比较他们的值即可,如果出现逆序就记录逆序对中的节点。
代码:转载自https://blog.csdn.net/geekmanong/article/details/50419323
class Solution {
public:
TreeNode* mistake1;
TreeNode* mistake2;
TreeNode* pre = NULL;
void recoverTree(TreeNode* root) {
recursive_traversal(root);
if (mistake1 != NULL && mistake2 != NULL) {
swap(mistake1->val, mistake2->val);
}
}
void recursive_traversal(TreeNode* root) {
if (root == NULL)
return;
if (root->left != NULL) { //中序遍历的第一步:遍历根的左子树
recursive_traversal(root->left);
}
if (pre != NULL && pre->val > root->val) { //中序遍历第二步,访问当前节点root的值
if (mistake1 == NULL) {
mistake1 = pre;
mistake2 = root;
}
else {
mistake2 = root;
}
}
pre = root; //pre指向当前节点,以便继续遍历到下一节点时可以维护上一节点
if (root->right != NULL) { //中序遍历第三步:遍历根的右子树
recursive_traversal(root->right);
}
}
};