//分析若有两个节点是错误的。深度遍历从最深处开始探索
//那么他们的公共祖先所在那棵树比如是不合法的
//一种是左右两个子树错误的那么找到那两个点
//一种是左子树上面的节点和它某个祖先交换了 需要
//一种是右子树上的节点和它某个祖先交换了
//那么他们的公共祖先所在那棵树比如是不合法的
//一种是左右两个子树错误的那么找到那两个点
//一种是左子树上面的节点和它某个祖先交换了 需要
//一种是右子树上的节点和它某个祖先交换了
//找到最开始出问题的根节点需要不断的回溯
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
#define MAX(a,b) ((a>b)?a:b)
#define MIN(a,b) ((a<b)?a:b)
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
void recoverTree(TreeNode* root) {
errorRoot = NULL;
int curMax, curMin;
findMaxMin(root, curMax, curMin);
if (errorRoot != NULL)
{
//修复
if (errorType == 2)//左子树中找最大
{
int curMax = errorRoot->val;
findMax(errorRoot->left, curMax);
swapValue(errorRoot, er1);
}
else if (errorType == 3)//右子树找最小的
{
int curMin = errorRoot->val;
findMin(errorRoot->right, curMin);
swapValue(errorRoot, er2);
}
else//都寻找
{
int curMax = errorRoot->val;
int curMin = errorRoot->val;
findMax(errorRoot->left, curMax);
findMin(errorRoot->right,curMin);
swapValue(er1, er2);
}
}
}
void swapValue(TreeNode*p1, TreeNode*p2)
{
int v = p1->val;
p1->val = p2->val;
p2->val = v;
}
void findMax(TreeNode*root,int&curMax)
{
if (root == NULL)return;
if (root->val > curMax)
{
curMax = root->val;
er1 = root;
}
findMax(root->left, curMax);
findMax(root->right, curMax);
}
void findMin(TreeNode*root, int&curMin)
{
if (root == NULL)return;
if (root->val < curMin)
{
curMin = root->val;
er2 = root;
}
findMin(root->left, curMin);
findMin(root->right, curMin);
}
void findMaxMin(TreeNode*root,int&curMax,int&curMin)//记录最大那个点
{
if (root == NULL) return;
if (root->left == NULL&&root->right == NULL) {
curMax = root->val;
curMin = root->val;
return;
}
int lefMax, lefMin, regMax, regMin;
findMaxMin(root->left, lefMax, lefMin);
findMaxMin(root->right, regMax, regMin);
if (root->right == NULL)
{
if (root->val < lefMax)
{
curMin = MIN(root->val, lefMin);
curMax = lefMax;
errorRoot = root;
errorType = 2;
return;
}
curMin = lefMin;
curMax = root->val;
return;
}
else if (root->left == NULL)
{
if (root->val > regMin)
{
curMax = MAX(root->val, regMax);
curMin = regMin;
errorRoot = root;
errorType = 3;
return;
}
curMin = root->val;
curMax = regMax;
return;
}
if (lefMax>regMin)//就是这个根出错是第一种情况
{
curMin = MIN(MIN(root->val, lefMin),regMin);
curMax = MAX(MAX(root->val, lefMax),regMax);
errorType = 1;
errorRoot = root;
return;
}
if (root->val < lefMax)
{
curMin = MIN(MIN(root->val, lefMin), regMin);
curMax = MAX(MAX(root->val, lefMax), regMax);
errorType = 2;
errorRoot = root;
return;
}
if (root->val > regMin)
{
curMin = MIN(MIN(root->val, lefMin), regMin);
curMax = MAX(MAX(root->val, lefMax), regMax);
errorType = 3;
errorRoot = root;
return;
}
curMax = regMax;
curMin = lefMin;
return;
}
private:
TreeNode*errorRoot;
TreeNode*er1;
TreeNode*er2;
int errorType;
};