题目
A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties:
- The left subtree of a node contains only nodes with keys less than the node's key.
- The right subtree of a node contains only nodes with keys greater than or equal to the node's key.
- Both the left and right subtrees must also be binary search trees.
A Complete Binary Tree (CBT) is a tree that is completely filled, with the possible exception of the bottom level, which is filled from left to right.
Now given a sequence of distinct non-negative integer keys, a unique BST can be constructed if it is required that the tree must also be a CBT. You are supposed to output the level order traversal sequence of this BST.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (≤1000). Then N distinct non-negative integer keys are given in the next line. All the numbers in a line are separated by a space and are no greater than 2000.
Output Specification:
For each test case, print in one line the level order traversal sequence of the corresponding complete binary search tree. All the numbers in a line must be separated by a space, and there must be no extra space at the end of the line.
Sample Input:
10 1 2 3 4 5 6 7 8 9 0
Sample Output:
6 3 8 1 5 7 9 0 2 4
运行结果
Case | Hint | Result | Run Time | Memory |
---|---|---|---|---|
0 | sample 换数字,但大小顺序不变 | Accepted | 3 ms | 424 KB |
1 | 完全平衡 | Accepted | 3 ms | 424 KB |
2 | 右边有余 | Accepted | 3 ms | 512 KB |
3 | 底层只多1个 | Accepted | 3 ms | 512 KB |
4 | 只有1个 | Accepted | 3 ms | 384 KB |
5 | 最大N随机 | Accepted | 4 ms | 424 KB |
程序
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
#define MaxSize 1000
int A[MaxSize];
int T[MaxSize];
void solve(int ALeft, int ARight, int TRoot);
int GetLeftNodeLength(int n);
bool compare(int a, int b);
void test_A();
int main()
{
int N;
//测试案例
//N = 10;
//test_A();
//读取有效数据大小
cin >> N;
//读取二叉树结点键值
for(int i=0; i<N; i++){
cin >> A[i];
}
//排序输入数组:从小到大
sort(A, A+N, compare);
//完全二叉搜索树构建算法
solve(0, N-1, 0);
//按照输出要求
for(int i=0; i<N-1; i++){
cout << T[i] << " ";
}
cout << T[N-1] <<endl;
return 0;
}
bool compare(int a, int b)
{
//从小到大排序
return a<b;
}
//递归函数功能:从片段序列[ALeft,ARight]中找到根结点键值,并给到T[TRoot]中
void solve(int ALeft, int ARight, int TRoot)
{
int n, L;
int LeftRoot, RightRoot;
//递归出口设计:当片段序列为空,即没有需要处理的序列时,返回
n = ARight - ALeft +1;
if(n == 0) return;
//递归逻辑:
//1、序列根结点的左结点数
//2、根据左结点数,得到根节点键值
//3、再向根结点的右边、左边继续递归,序列不断减小
L = GetLeftNodeLength(n);
T[TRoot] = A[ALeft + L];
LeftRoot = TRoot * 2 + 1; //由于TRoot从0开始,故左孩子结点索引需要加1
RightRoot = LeftRoot + 1;
solve(ALeft, ALeft + L - 1, LeftRoot);
solve(ALeft + L +1, ARight, RightRoot);
}
int GetLeftNodeLength(int n)
{
int L, k, X, MX;
//由层数、最后一层剩余结点数、总结点个数的关系式可得
k = log(n+1)/log(2); //以2为底的对数
X = n - pow(2, k) +1;
MX = pow(2, k-1); //最底层最大结点数
X = X < MX ? X:MX; //X所取不得超过MX
L = pow(2, k-1) -1 +X;
return L;
}
void test_A()
{
A[0] = 1;
A[1] = 2;
A[2] = 3;
A[3] = 4;
A[4] = 5;
A[5] = 6;
A[6] = 7;
A[7] = 8;
A[8] = 9;
A[9] = 0;
//T = 6 3 8 1 5 7 9 0 2 4
}