PAT甲级1064 Complete Binary Search Tree (30分)​​​​​​​ 二叉树数组存储+二叉树的遍历 C/C++/Python

6 篇文章 0 订阅
2 篇文章 0 订阅

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 0

Sample Output:

6 3 8 1 5 7 9 0 2 4

 题目大意:

二叉搜索树(BST)是具有以下定义的一种二叉树:

  • 其左子树的所有节点(若存在)的关键字都比根节点的小;
  • 其右子树的所有节点(若存在)的关键字都比根节点的小;
  • 其左/右子树自身也是一颗二叉搜索树(BST)

完全二叉树(CBT)

若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树

现在给定N个关键字,按层序遍历打印由这些关键字的树节点组成的特定二叉树,这个二叉树既是二叉搜索树又是完全二叉树,也就是完全二叉搜索树

 输入:第一行N:多少个节点(关键字)

第二行N个非负整数:关键字序列


算法思路:

  • 输出是按层序遍历的,那么此二叉树用数组存储法最佳,因为二叉树的数组顺序就是层序遍历的顺序;
  • 数组从下标1开始,则以下标i表示的每个节点,其左孩子节点是下标(2*i)、右左孩子节点是下标(2*i+1)。
  • 如何构造此二叉树呢?注意二叉搜索树的中序遍历就是此树关键字的非降序排序。先将输入的N个数按非降序排列,即可得到此树中序遍历时的输出序列,那只要当做此树已经构造好了,按中序遍历此树,将访问根节点的操作替换为赋值根节点即可构造此树。
  • 最后按存储二叉树的数组顺序遍历即为层序遍历。

C++代码如下:

#include<cstdio>
#include<algorithm>
using namespace std;
const size_t MAX_N = 1001;
int NUM;	//树节点个数
int A[MAX_N];	//BST中序遍历时的序列
int BT[MAX_N];	//二叉树的数组表达,其中BT[0]禁用!
size_t ib = 0;	//用于中序遍历BST树,即BST[]按序遍历
void inorder(size_t i) {
	if (i > NUM)return;	//数组树越界——>子节点不存在
	inorder(2 * i);		//访问左子树
	BT[i] = A[ib++];	//根节点(按BST中序遍历顺序写入)
	inorder(2 * i + 1);	//访问右子树
}
int main() {
	scanf("%d\n", &NUM);
	for (size_t i = 0; i < NUM; i++) {
		scanf("%d", &A[i]);
	}
	sort(A, A + NUM);		//非降序排序等同BST的中序遍历输出顺序
	inorder(1);		//从根节点开始按中序遍历赋值
	printf("%d", BT[1]);	//堆存储二叉树的顺序就是层序遍历的顺序,直接按序输出即可。
	for (size_t i = 2; i <= NUM; i++) {
		printf(" %d", BT[i]);
	}puts("");
	system("pause");
	return 0;
}

Python3 代码如下:

num = int(input())
A = sorted([int(a) for a in input().split(' ')])
BT = [0 for i in range(num + 1)]
def inOrder( i: int):
    global num,A,BT
    if i <= num:
        inOrder(2 * i)
        BT[i] = A[0];
        A = A[1:]
        inOrder(2 * i + 1)
inOrder(1)
print(' '.join(map(str,BT[1:])))

C语言代码如下:

由于C语言qsort要写比较函数,注意题目中“All the numbers in a line are separated by a space and are no greater than 2000.”,所有元素是[0,2000]的整数,可以用一维桶排序解决非递减遍历BST的问题。

#include<stdio.h>
#include<stdlib.h>
#define FOR(I,S,E) for(int I=(S);I<(E);I++)
#define MAX_N 1001
int BT[MAX_N];	//二叉树的数组表达,其中BT[0]禁用!
#define MAX 2000	//non-negative integer,no greater than 2000
int Count[MAX + 1] = { 0 };	//桶排序,数值范围限定在0~2000
void push(int a) {++Count[a];}
int pop() {	//从Count中取出最小元素并移除
	static int a = 0;	//BST遍历的关键字,对应Count的下标
	while (a <= MAX && Count[a] <= 0)++a;
	--Count[a];
	return a;
}
size_t NUM;	//二叉树节点数
void inorder(size_t i) {
	if (i > NUM)return;	//数组树越界——>子节点不存在
	inorder(2 * i);		//访问左子树
	BT[i] = pop();		//根节点(按BST中序遍历顺序写入)
	inorder(2 * i + 1);	//访问右子树
}
int main() {
	scanf("%d\n", &NUM);
	FOR(i, 0, NUM) {
		int a; scanf("%d", &a);
		push(a);
	}	// Count[a]=m 表示输入的N个数中有m个元素a。
	inorder(1);		//从根节点开始按中序遍历赋值
	printf("%d", BT[1]);	//堆存储二叉树的顺序就是层序遍历的顺序,直接按序输出即可。
	for (size_t i = 2; i <= NUM; i++) {
		printf(" %d", BT[i]);
	}puts("");
	system("pause");
	return 0;
}

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值