根据完全二叉搜索树的性质,将输入的数据进行从小到大排序排序,计算出左子树的规模,然后求出根节点的位置,然后把根节点放入数组,然后递归左右儿子节点,
注意求左子树的个数函数里传入的n是会随着递归变化而变化的,之前未注意到这一点,所以一直部分正确
#include <stdio.h> #include <stdlib.h> #include<algorithm> #include<math.h> using namespace std; void Solve(int ALeft, int ARight, int TRoot, int A[], int T[]); int Get_Left_Nodes(int n); int Min(int a, int b); int main(int argc, char const argv[]) { // freopen("test.txt", "r", stdin); int N, tmp; scanf("%d", &N); int A[N], T[N]; for (int i = 0; i < N; ++i){ scanf("%d", &tmp); A[i] = tmp; } sort(A,A+N); int ALeft = 0, ARight = N -1, TRoot = 0; Solve(ALeft, ARight, TRoot, A, T); for (int i = 0; i < N; ++i) { if(i == 0) { printf("%d", T[i]); } else printf(" %d", T[i]); } return 0; } void Solve(int ALeft, int ARight, int TRoot, int A[], int T[]) { int n; n = ARight - ALeft + 1; //结点数n if(n == 0) return; int L, LeftTRoot, RightTRoot; L = Get_Left_Nodes(n); //计算出n个结点的完全二叉树的左子树的结点个数 T[TRoot] = A[ALeft + L]; LeftTRoot = TRoot *2 + 1; RightTRoot = LeftTRoot + 1; Solve(ALeft, ALeft + L - 1, LeftTRoot, A, T); Solve(ALeft + L + 1, ARight, RightTRoot, A, T);//Aleft不要忘了+1 } int Get_Left_Nodes(int n) { int H = 0, tmp = 1, X, L;//X为左子树最下一层的结点数 int N = n; while(N > 1) { N /= 2; H++;//树的高度 } for (int i = 0; i < H - 1; ++i) { tmp *= 2; } X = n - 2*tmp + 1; X = Min( X, tmp ); L = tmp - 1 + X; return L; } int Min(int a, int b) { return (a < b) ? a : b; }
看了别人的之后,发现一棵二叉排序树的中序遍历序列是递增有序的
#include<stdio.h> #include<stdlib.h> #include<iostream> #include<queue> #include<algorithm> #include<map> #include<vector> #include<cstring> #include<math.h> #include<stack> using namespace std; int node[1005]; int tree[1005]; int pos,n; void build(int root) { if(root > n) return ; int lson=root*2; int rson=root*2+1; build(lson); tree[root]=node[pos++]; build(rson); } int main() { cin>>n; for(int i=0;i<n;i++) { cin>>node[i]; } sort(node,node+n); pos=0; build(1); for(int i=1;i<=n;i++) { if(i!=1) cout<<" "; cout<<tree[i]; } }