Complete Binary Search Tree
问题分析
Complete Binary Search Tree代表完全二叉搜索树,包含两个概念,一个为完全二叉树,另一个为二叉搜索树。示意如下:
输入输出分析
由题意可知,在给定一个不同的非负整数键序列,可以得到一个唯一得完全二叉搜索树。在给定序列为:1 2 3 4 5 6 7 8 9 0
可以唯一得到一棵完全二叉搜索树。题目要求输出为构成树得层序遍历得结果,也即6 3 8 1 5 7 9 0 2 4。
树的表示方法
链表与数组两种方法。
本道题需要的操作为:
1.填写数字(某种遍历)
2.层序遍历
3.完全二叉树,不浪费空间。
4.层序遍历==直接顺序输出。
采用数组的方式进行存储。下标按顺序放置,数组元素的值代表树的Data值。
核心算法
因为是完全二叉树,因此我们可以通过序列元素的个数来确定树的高度和左子树节点的个数。通过排序后的序列和元素个数可以轻松找到对应完全二叉树的树根的位置,如图为6。
如何计算左子树节点的个数
X范围为[0, 2^H-1],当X只有一个节点时,X的左子树个数为0,因此左子树个数最小为0,不为1.
AC代码
#include<algorithm>
#include<iostream>
using namespace std;
int N;
int Node[1002];
int T[1002];
int GetLeftLength(int n)
{
int H = floor(log2(n));
int X = n - (pow(2, H) - 1);
if (X > pow(2, H - 1))
X = pow(2, H - 1);
X += (pow(2, H - 1) - 1);
if (X < 0)
X = 0;
return X;
}
void solve(int ALeft, int ARight, int TRoot)
{
int n, L;
int LeftTRoot, RightTRoot;
n = ARight - ALeft + 1;
if (n == 0) return;
L = GetLeftLength(n);/* 计算出n个节点得树,左子树有几个*/
T[TRoot] = Node[ALeft + L];
LeftTRoot = TRoot * 2 + 1;
RightTRoot = LeftTRoot + 1;
solve(ALeft, ALeft + L-1, LeftTRoot);
solve(ALeft + L + 1, ARight, RightTRoot);
}
int main()
{
cin >> N;
for (int i = 0; i < N; ++i)
cin >> Node[i];
sort(Node, Node + N);
solve(0, N-1, 0);
for (int i = 0; i < N - 1; ++i)
cout << T[i] << " ";
cout << T[N - 1] << endl;
return 0;
}
参考
[1]:https://www.icourse163.org/learn/ZJU-93001#