题目地址
https://pta.patest.cn/pta/test/16/exam/4/question/669
5-7 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 NN (\le 1000≤1000). Then NN 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:
101 2 3 4 5 6 7 8 9 0
Sample Output:
6 3 8 1 5 7 9 0 2 4
/*评测结果时间 结果 得分 题目 编译器 用时(ms) 内存(MB) 用户2017-06-29 10:45 正在评测 0 5-7 gcc 无 无 测试点结果测试点 结果 得分/满分 用时(ms) 内存(MB)测试点1 答案正确 18/18 1 1测试点2 答案正确 3/3 2 1测试点3 答案正确 2/2 1 1测试点4 答案正确 2/2 1 1测试点5 答案正确 3/3 1 1测试点6 答案正确 2/2 3 1完全二叉搜索树结构:数组形式存储完全树,可以很方便进行层序遍历 解法:思考后发现完全二叉搜索树的子树也是完全二叉搜索树。故先将接收到的数据排序,递归计算一个节点的左子树和右子树数量,类似于快排,每次可以确定root的值。然后按顺序打印数组即可。 */#include#define MAXLEN 2000int workarray[MAXLEN];int CBST[MAXLEN+1];//0号元素空着,从1号开始左子树2*root,右子树2*root+1;int NODECOUNT[MAXLEN+1];int Len;void swap(int *a,int *b){ int temp; temp=*a; *a=*b; *b=temp; }void InsertionSort(int A[],int N){ int i; int k; for(i=1;i 0;i--)//在1开头的数组中,有效下标范围应该是1~Len { NODECOUNT[i/2] += NODECOUNT[i]+1; //父节点的子树,加上本节点的子树,再加上该节点自身 }}void CalcTree(int raw[],int calc[],int left,int index){ if (index>Len) return; //越界了,没子树 int raw_position=left+(2*index>Len?0:NODECOUNT[2*index]+1);//注,函数首次调用,left最初传入的是0, 判断是否为叶节点,如果没有左子树,那么它自己就是left //此处加个注释说明下,一个坐标的构成。left(此递归段偏移起点)+NODECOUNT[2*index](所求的点的左儿子的全部结点数量)+1(该结点本身,即此递归段的root) calc[index]=raw[raw_position]; CalcTree(raw,calc,left,2*index);//递归左子树 CalcTree(raw,calc,raw_position+1,2*index+1);//递归右子树 }int main(){ GetInput(); InsertionSort(workarray,Len);// printf("done sort\n");// Outputraw();// printf("\n"); CountNodes(); CalcTree(workarray,CBST,0,1); Output(); printf("\n");// Outputcount();}