PTA-mooc完整题目解析及AC代码库:PTA(拼题A)-浙江大学中国大学mooc数据结构全AC代码与题目解析(C语言)
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
完全二叉搜索树
顾名思义,完全二叉搜索树就是完全二叉树和二叉搜索树的综合体,同时满足二者的性质,例如下面这棵树就是一棵完全二叉搜索树。

从结构上看,它是一棵完全二叉树,而其每个结点的值也满足二叉搜索树的要求。
题目分析
给定一串数值各不相同的非负整数值,求以该串数建立的完全二叉搜索树的层序遍历输出序列。
关键点分析
这个题目总体有两个关键点:
- 如何表示存储整个完全二叉搜索树
- 怎样将给定的各个整数值放入树中对应的正确位置上
针对第一个问题,因为该树是一个完全二叉树,因此使用数组或链表形式都行,而因为最终要求层序遍历输出,而以数组方式存储的完全二叉树的顺序就是层序遍历的顺序,因此可以使用数组方式存储,0索引存储所有结点数,根节点的索引为1,每个结点的左右孩子索引分别为 2i 和 2i+1。
对于第二个问题,因为二叉搜索树的中序遍历序列正好等于所有结点按从小到大排列的序列,因此可以利用这一特性,先对输入的无序数据进行排序,然后以中序遍历方式访问该树,然后插入对应结点即可。
具体代码实现非常简单,使用一个递归的中序遍历即可
#include <stdio.h>
#include <stdlib.h>
int comp(const void *a, const void *b)
{
return *(int *)a - *(int *)b;
}
/* 读入所有输入结点值,并排序 */
void initInputArr(int *arr, int N)
{
int i;
for (i = 0; i < N; ++i)
{
scanf("%d", &arr[i]);
}
qsort(arr, N, sizeof(int), comp);
}
// 不用额外传入数据长度,数据长度存在tree[0]上
void makeCBST(int *tree, int *arr, int pos, int *i)
{
// 如果树的位置超出了边界或者输入数据已用完,则返回
if (pos < 1 || pos > tree[0] || (*i) == tree[0]) return;
else { // 中序遍历
makeCBST(tree, arr, pos * 2, i);
tree[pos] = arr[(*i)++];
makeCBST(tree, arr, pos * 2 + 1, i);
}
}
void printCBST(int *tree)
{
int i;
for (i = 1; i <= tree[0]; ++i) {
if (i != 1) printf(" ");
printf("%d", tree[i]);
}
}
int main()
{
int N, pos, i;
int *arr, *tree;
scanf("%d", &N);
arr = (int *)malloc(N * sizeof(int)); // 用来存放输入结点并排序
tree = (int *)malloc((N + 1) * sizeof(int)); // 存放完全二叉搜索树的所有结点,第一个位置存放结点个数
tree[0] = N;
pos = 1, i = 0;
initInputArr(arr, N);
makeCBST(tree, arr, pos, &i);
printCBST(tree);
free(arr);
free(tree);
return 0;
}