1064. Complete Binary Search Tree (30)
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 0Sample Output:
6 3 8 1 5 7 9 0 2 4
解题要点是:用先序遍历求解
用数组还是链表?应该用数组,该程序最后要求输出层序遍历,数组就是按照层序遍历来存储树的。通常,我们采用链表来表示的原因是,如果该树左斜或者右斜严重,用数组表示会造成存储空间的浪费,但是这道题中是完全二叉树,用数组不会造成空间浪费,所以应该使用数组来进行操作。
如果我知道左子树节点个数,那么我就可以知道根节点在从小到大排列的数组中的index。
首先对输入的数据进行排序,我们直接调用库函数Arrays.sort()
运行结果:
代码如下:
import java.util.Arrays;
import java.util.Scanner;
public class CompleteBinarySearchTree {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
// 需要两个数组,数组arr[]存数据,数组arr1[]存储结果
int[] arr = new int[N];
int[] arr1 = new int[N];
//读入数据,存储在arr[]中
for (int i = 0; i < N; i++) {
arr[i] = sc.nextInt();
}
//注意,这里排序直接调用了库函数
Arrays.sort(arr);
// 调用solve函数
solve(arr, arr1, 0, N - 1, 0);
for (int i = 0; i < N; i++) {
System.out.print(arr1[i]);
if (i != N - 1)
System.out.print(" ");
}
sc.close();
}
public static void solve(int[] arr, int[] arr1, int left, int right, int root) {
int length = right - left + 1;
if (length == 0)
return;
int leftNum = getLeftLength(length);
arr1[root] = arr[left + leftNum];
int leftRoot = 2 * root + 1;
int rightRoot = leftRoot + 1;
solve(arr, arr1, left, left + leftNum - 1, leftRoot);
solve(arr, arr1, left + leftNum + 1, right, rightRoot);
}
//获取左子树的节点个数:1.java中log()是以自然对数为底,所以必须除以log(2)。
//而且结果是double类型,需要进行强制转换
//Math.pow(2,height) or Math.pow(2,height-1)要考虑清楚。
public static int getLeftLength(int n) {
int height = (int) ((Math.log(n + 1) / Math.log(2)));
int x = n - (int) Math.pow(2, height) + 1;
x = Math.min((int) Math.pow(2, height - 1), x);
return (int) Math.pow(2, height - 1) - 1 + x;
}
}