本题源自leetcode
-----------------------------------------------------------
思路1,中序遍历 找出左子树大于父节点的值,再找出右子树小于父节点的值,然后交换,用指针pre保存中序遍历的父节点
TreeNode* a=NULL;
TreeNode* b=NULL;
TreeNode* pre=NULL;
public:
void recoverTree(TreeNode *root) {
if(root==NULL)
return;
dfs(root);
if(a&&b)
swap(a->val,b->val);
}
//中序遍历
void dfs(TreeNode* root){
if(root==NULL)
return;
dfs(root->left);
if(pre&&pre->val>root->val){
if(a==NULL) //a 指向第一个错误的节点(左子树节点大于根节点)
a=pre;
b=root; //b指向根节点比右子树大的节点
}
pre=root;
dfs(root->right);
}
思路2 :
用额外的空间o(n) ,中序遍历现在的二叉树,然后排序,再把值赋给二叉树。
void recoverTree(TreeNode *root) {
if(root==NULL)
return;
vector<TreeNode*> trees;
vector<int> inorderVal;
Inorder(root,trees,inorderVal);
sort(inorderVal.begin(),inorderVal.end());
for(int i=0;i<trees.size();i++){
trees[i]->val=inorder[i];
}
}
void Inorder(TreeNode* root,vector<TreeNode*>& trees,vector<int>& inorderVal){
if(root==NULL)
return;
Inorder(root->left,trees,inorderVal);
trees.push_back(root);
inorderVal.push_back(root->val);
Inorder(root->right);
}