一棵二叉树原本是搜索二叉树,但是其中有两个节点调换了位置,使得这棵二叉树不再是搜索二叉树,请按升序输出这两个错误节点的值。(每个节点的值各不相同)
第一行输入两个整数 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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Stack;
import java.util.LinkedList;
import java.util.Queue;
class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 构建二叉树
String[] params = br.readLine().split(" ");
int n = Integer.parseInt(params[0]);
TreeNode root = new TreeNode(Integer.parseInt(params[1]));
HashMap<Integer, TreeNode> map = new HashMap<>();
map.put(root.val, root);
for(int i = 0; i < n; i++){
params = br.readLine().split(" ");
int val = Integer.parseInt(params[0]);
int leftVal = Integer.parseInt(params[1]);
int rightVal = Integer.parseInt(params[2]);
TreeNode node = map.get(val);
if(leftVal != 0) {
node.left = new TreeNode(leftVal);
map.put(leftVal, node.left);
}
if(rightVal != 0) {
node.right = new TreeNode(rightVal);
map.put(rightVal, node.right);
}
}
System.out.println(isBST(root));
}
private static String isBST(TreeNode root) {
int prev = Integer.MIN_VALUE;
int error1 = 0, error2 = 0;
Stack<TreeNode> stack = new Stack<>();
while(!stack.isEmpty() || root != null){
while(root != null){
stack.push(root);
root = root.left;
}
if(!stack.isEmpty()){
root = stack.pop();
if(root.val <= prev) {
// 破坏了中序遍历的单调递增特性
if(error1 == 0) error1 = prev;
error2 = root.val;
}
prev = root.val;
root = root.right;
}
}
if(error1 < error2)
return error1 + " " + error2;
else
return error2 + " " + error1;
}
} #include <bits/stdc++.h>
using namespace std;
struct Tree{
int left, right;
};
vector<Tree> T;
vector<int> v1;
void BST(int r){
if(r==0)
return;
BST(T[r].left);
v1.push_back(r);
BST(T[r].right);
}
int main(){
int n, r, a, b, c;
scanf("%d%d", &n, &r);
T.resize(n+1);
for(int i=0;i<n;i++){
scanf("%d%d%d", &a, &b, &c);
T[a].left = b;
T[a].right = c;
}
BST(r);
vector<int> v2(v1);
sort(v2.begin(), v2.end());
for(int i=0,k=0;i<v2.size();i++){
if(v1[i]!=v2[i]){
k++;
if(k==1)
printf("%d ", v2[i]);
else{
printf("%d\n", v2[i]);
break;
}
}
}
return 0;
} //
// Created by yuanhao on 2019-9-2.
//
#include <iostream>
#include <cstring>
using namespace std;
/**
* 对无序的几位进行排序 O(n)
*/
void sort(int *a, int n, int *wrong_index, int &wrong_index_len) {
for (int i = 0; i < n - 1; ++i) {
if (a[i] > a[i + 1]) {
if (wrong_index[wrong_index_len - 1] != i) {
wrong_index[wrong_index_len++] = i;
}
if (wrong_index[wrong_index_len - 1] != i + 1) {
wrong_index[wrong_index_len++] = i + 1;
}
if (wrong_index_len >= 4) {
// 两个数字交换,最多只有四个可能的位置不对
break;
}
}
}
// 对最多四个位置的数字进行排序,随便选排序算法,冒泡就行
for (int i = 0; i < wrong_index_len - 1; ++i) {
for (int j = 0; j < wrong_index_len - 1 - i; j++) {
if (a[wrong_index[j]] > a[wrong_index[j + 1]]) {
int tmp = a[wrong_index[j]];
a[wrong_index[j]] = a[wrong_index[j + 1]];
a[wrong_index[j + 1]] = tmp;
}
}
}
}
/**
* 中序遍历 O(n)
*/
void mid_visite(int root, int *lch, int *rch, int *arr, int &num) {
if (lch[root] != 0) {
mid_visite(lch[root], lch, rch, arr, num);
}
arr[num++] = root;
if (rch[root] != 0) {
mid_visite(rch[root], lch, rch, arr, num);
}
}
//题目描述
//一棵二叉树原本是搜索二叉树,但是其中有两个节点调换了位置,使得这棵二叉树不再是搜索二叉树,请按升序输出这两个错误节点的值。(每个节点的值各不相同)
//
//输入描述:
//第一行输入两个整数 n 和 root,n 表示二叉树的总节点个数,root 表示二叉树的根节点。
//
//以下 n 行每行三个整数 fa,lch,rch,表示 fa 的左儿子为 lch,右儿子为 rch。(如果 lch 为 0 则表示 fa 没有左儿子,rch同理)
//
//ps:节点的编号就是该节点的值。
//输出描述:
//请按升序输出这两个错误节点的值。
//示例1
//输入
//复制
//3 1
//1 2 3
//2 0 0
//3 0 0
//输出
//复制
//1 2
int main() {
int n = 0;
int root = 0;
cin >> n >> root;
int lch[n];
int rch[n];
for (int i = 0; i < n; ++i) {
int f, l, r;
cin >> f >> l >> r;
lch[f] = l;
rch[f] = r;
}
// 前面都是输入
int num = 0;
int arr[n];
int sorted_arr[n];
mid_visite(root, lch, rch, arr, num); // 实际上这个num最后是等于n的
memcpy(sorted_arr, arr, num * sizeof(int));
// 搜索树中序遍历的结果应该是一个有序的数组,这里有两位被交换,会导致最多四个位置的数字无序,排序之后就知道是哪两位交换了
// 不用完整的排序,那样会超时,自己写一个排序算法
int wrong_index[4];
int wrong_index_len = 0;
sort(sorted_arr, num, wrong_index, wrong_index_len);
// 输出结果
for (int i = 0; i < wrong_index_len; ++i) {
if (arr[wrong_index[i]] != sorted_arr[wrong_index[i]]) {
cout << sorted_arr[wrong_index[i]] << " ";
}
}
} #include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
struct node{
int lchild;
int rchild;
};
vector<node> v;
vector<int> v1,v2;
void inorder(int node){
if(node==0)
return;
inorder(v[node].lchild);
v1.push_back(node);
v2.push_back(node);
inorder(v[node].rchild);
}
int main(){
int n,root;
int n1,n2,n3;
scanf("%d %d",&n,&root);
v.resize(n+1);
for(int i=0;i<n;++i){
scanf("%d %d %d",&n1,&n2,&n3);
v[n1].lchild=n2;
v[n1].rchild=n3;
}
inorder(root);
sort(v1.begin(),v1.end());
int flag=0;
for(int i=0;i<v1.size();++i){
if(v1[i]!=v2[i])
if(flag==0)
{
printf("%d",v1[i]);
flag=1;
}else{
printf(" %d",v1[i]);
break;
}
}
return 0;
} #include<bits/stdc++.h>
using namespace std;
// pre记录上一步访问的结点
// a,b即为所求
void Inorder(int root,int* lc,int* rc,int& pre,int& a,int& b,bool& first)
{
if(!root) return;
Inorder(lc[root],lc,rc,pre,a,b,first);
// 因为是BST,中序遍历应为升序
// 当出现降序时 说明找到了错误结点
if(root<pre)
{
// 根据两个交换的结点的位置 可能出现一次或两次降序
if(first)
{
a = pre;
b = root;
first = !first;
}
else b = root;
}
pre = root;
Inorder(rc[root],lc,rc,pre,a,b,first);
}
int main()
{
int n,root;
cin>>n>>root;
int p;
int* lc = new int[n+1];
int* rc = new int[n+1];
for(int i=0;i<n;++i)
{
cin>>p;
cin>>lc[p]>>rc[p];
}
int ans1,ans2;
int pre = INT_MIN;
bool first = true;
Inorder(root,lc,rc,pre,ans1,ans2,first);
ans1 = max(ans1,ans2);
ans2 = min(ans1,ans2);
cout<<ans2<<" "<<ans1<<endl;
return 0;
}