一棵二叉树原本是搜索二叉树,但是其中有两个节点调换了位置,使得这棵二叉树不再是搜索二叉树,请按升序输出这两个错误节点的值。(每个节点的值各不相同)
第一行输入两个整数 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; }