PAT 甲级 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.

输入

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.

输出

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.

思路

题目给了序列,从小到达排序后为中序,现在我们就是需要通过确定根来进行建树,题目给了条件为完全二叉树,因此tree数组每一个的子孩子为2i+1和2i+2。然后我们可以算一下满树的情况下总共有多少节点,对应的分别为0 1 3 7 15…因此递归建树时,我们可以求出当前序列长度len,看看len包含的节点中如果满树有多少层,假如此时len=10,那么可以发现应该有4层,最后一层少了5个节点,在确定根时我们要假装把这棵树补气,相当于此时给树补齐5个节点,15/2为根。做到这里发现那这么算应该是7为根,但答案为6,这是因为此时做子树少了一个节点,因此我们要减去这个节点。具体公式为(15-7)/2 - (10-7),若小于0则说明满的,不用补齐,否则应减去这个值。

代码

#include<iostream>
#include<cstdio>
#include<stdlib.h>
#include<string>
#include<algorithm>
using namespace std;
int tree[10000];
int in[10000];
int number[100];
int ans[10000];
void create(int l, int r,int cur)
{
	if (l == r)
	{
		ans[cur]=in[l];
		return;
	}
	else if(l>r)
	{
		return ;
	}
	int len = r - l + 1;
	int c = 1;
	while (len > number[c])
	{
		c++;
	}
	int d = (number[c] - number[c - 1]) / 2 - (len - number[c - 1]);
	if (d < 0)
	{
		d = 0;
	}
	int rootId = number[c] / 2 + l - d;
	ans[cur] = in[rootId];
	create(l, rootId - 1, 2 * cur + 1);
	create(rootId + 1, r, 2 * cur + 2);
}
int main()
{
	int N;
	cin >> N;
	for (int i = 0; i < N; i++)
	{
		cin >> in[i];
	}
	number[0] = 0;
	for (int i = 1; i < 15; i++)
	{
		number[i] = (number[i - 1] + 1) * 2 - 1;
	}
	sort(in, in + N);
	create(0, N - 1,0);
	for (int i = 0; i < N; i++)
	{
		printf("%d", ans[i]);
		if (i < N - 1)
		{
			printf(" ");
		}
	}
	cout << endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值