PAT 1064 Complete Binary Search Tree 完全二叉搜索树填值

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

题目大意:已知一棵完全二叉树的节点个数,和树上的所有的节点的值,要求构造完全搜索二叉树,并输出层次遍历结果。
解题思路:这道题又是一道利用已知的树结构和节点的值构造二叉搜索树的题。首先可以参考一下我的另一篇博客,两道题的解题思路是一样的。

下面详细展示下本题的构造过程:

一开始我们知道二叉搜索树中的值有1 2 3 4 5 6 7 8 9 0
从小到达排序后为:0 1 2 3 4 5 6 7 8 9
由于题目中二叉树为完全二叉树,所以使用数组构造二叉树,树的结构如下(树节点上面的数字表示节点在数组中的索引):
mWxcQJ.md.jpg
接下来我们考虑往里面填值,一开始填写根节点的值,由于二叉树中左子树的值都小于根节点,右子树的值大于或等于根节点的值,所以如果我们知道了左子树中节点的个数我们就知道了树的根节点处应该填写的值,如图我们知道左子树有6个节点,所以排好序的序列中的第7个数应该填在根节点处,所以根处填6,填写后结果如下:
mWz29S.jpg
根节点的值填写完成后我们用同样的方法填左右子树:
此时左右子树结构已知
左子树的值为0 1 2 3 4 5
右子树的值为7 8 9
依然按照上面的步骤,先填写根节点,然后将问题分为两个子问题。
mfSK4f.jpg
这样一层一层填写下去后最后就能得到构造完成的结果:
mfSjG8.jpg
最后需要的层次遍历的结果也就是数组遍历的结果:
6 3 8 1 5 7 9 0 2 4

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1005;

int tree[maxn<<1];
int n;

// 返回以index为根节点的子树的节点的个数 
int cntNode(int index){
	int ans = 0;
	if(index >= n)
		return ans;

	stack<int> sk;
	sk.push(index);
	
	while(!sk.empty()){
		index = sk.top();sk.pop();
		ans++;
		if(2*index+1 < n)
			sk.push(2*index+1);
		if(2*index+2 < n)
			sk.push(2*index+2);
	}
	
	return ans;
}

void build(vector<int>& num, int root){
	if(num.size() == 0)
		return ;
	int leftCnt = cntNode(root*2+1);
	
	vector<int> leftNum, rightNum;
	for(int i = 0;i < num.size(); i++){
		if(i < leftCnt)
			leftNum.push_back(num[i]);
		else if(i != leftCnt)
			rightNum.push_back(num[i]);
	}
	
	tree[root] = num[leftCnt];
	
	if(leftNum.size() > 0)
		build(leftNum, 2*root+1);
	if(rightNum.size() > 0)
		build(rightNum, 2*root+2);
	
} 

int main(int argc, char const *argv[])
{
	cin >> n;
	vector<int> num(n);
	for(int i = 0;i < n; i++)
		cin >> num[i];
	
	sort(num.begin(), num.end());
	
	build(num, 0);
	
	for(int i = 0;i < n; i++)	{
		cout << tree[i];
		if(i != n-1)
			cout << " ";
	}
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值