PAT1064:Complete Binary Search Tree (Java实现)

1064. Complete Binary Search Tree (30)

时间限制
100 ms
内存限制
32000 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

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




解题要点是:用先序遍历求解

用数组还是链表?应该用数组,该程序最后要求输出层序遍历,数组就是按照层序遍历来存储树的。通常,我们采用链表来表示的原因是,如果该树左斜或者右斜严重,用数组表示会造成存储空间的浪费,但是这道题中是完全二叉树,用数组不会造成空间浪费,所以应该使用数组来进行操作。


如果我知道左子树节点个数,那么我就可以知道根节点在从小到大排列的数组中的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;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值