题目描述
一棵二叉树原本是搜索二叉树,但是其中有两个节点调换了位置,使得这棵二叉树不再是搜索二叉树,请按升序输出这两个错误节点的值。(每个节点的值各不相同)
输入描述:
第一行输入两个整数 n 和 root,n 表示二叉树的总节点个数,root 表示二叉树的根节点。
以下 n 行每行三个整数 fa,lch,rch,表示 fa 的左儿子为 lch,右儿子为 rch。(如果 lch 为 0 则表示 fa 没有左儿子,rch同理)
ps:节点的编号就是该节点的值。
输出描述:
请按升序输出这两个错误节点的值。
输入
3 1
1 2 3
2 0 0
3 0 0
输出
1 2
#include<bits/stdc++.h>
using namespace std;
struct TreeNode{
int value;
TreeNode*left,*right;
TreeNode(int value_):value(value_),left(NULL),right(NULL){}
};
map<int,TreeNode*>mp;
int pre = -1;
int ans[2]={-1};
void Inorder(TreeNode*root){
if(root==NULL)
return;
Inorder(root->left);
//二叉搜索树:中序遍历为升序数组
//有两种情况:
//1. 1 2 4 3 5,错误的两个节点中序相邻,这时中序遍历只有一次是降序,其他都是升序
//2. 1 5 3 4 2,错误两个节点中序不相邻,两次降序,
if(pre>root->value){
if(ans[0]==-1){
//情况一
ans[0] = root->value;
ans[1] = pre;
}else{
//情况二,已经有一次降序了,只需要把第二次的降序节点替代第一个的即可
ans[0] = root->value;
}
}
pre = root->value;
Inorder(root->right);
}
TreeNode* createNode(int v){
TreeNode*root;
if(mp.count(v)==0){
root= new TreeNode(v);
mp[v] = root;
}else{
root=mp[v];
}
return root;
}
int main(){
int n,r;
cin>>n>>r;
TreeNode* root = new TreeNode(r);
mp[r] = root;
for(int i=0;i<n;i++){
int fa,lch,rch;
scanf("%d %d %d",&fa,&lch,&rch);
TreeNode*cur = createNode(fa);
if(lch){
cur->left = createNode(lch);
}else{
cur->left =NULL;
}
if(rch){
cur->right = createNode(rch);
}else{
cur->right =NULL;
}
}
Inorder(root);
cout<<ans[0]<<" "<<ans[1]<<endl;
}