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.
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.
10
1 2 3 4 5 6 7 8 9 0
结尾无空行
Sample Output:
6 3 8 1 5 7 9 0 2 4
????????这题的思路其实非常简单,问题在于如何简洁的实现。
????????思路其实是:将输入的一堆数据按照升序排列好之后,计算得到左子树的结点个数后,因为所有左子树结点值都小于根结点,所有右子树结点值都大于或等于根结点,那么在排好的序列中左子树个数+1的那个数肯定就是根结点。
????????那么怎么得到左子树的结点数呢,因为这又是完全二叉树,其有很多特殊性质:
1、层数为log2N(N为结点数)
3、每层的结点数最大为2^(k-1)(k为第几层)
3、前k层的总的结点数为2^k - 1
????????完全二叉树除了叶结点不满以外,其它应该都是满的,而叶结点也是从左到右排布的,中间没有空的,那么如图:
? ? ? ? ?至于思路的实现,可以链表,也可以数组,但我个人认为数组会更简单,因为涉及层次遍历。并且用一组从小到大排好的数来构造完全二叉搜索树,如果用链表,会非常麻烦。
#include<stdio.h> #include<algorithm> ? ?//sort函数? #include<cmath> ? ? ? ? ?//pow函数? #include<vector> ? ? ? //sort函数,和algorithm一起才能使用sort? #define Maxsize 2005 using namespace std;
int num[Maxsize], BST[Maxsize]; int Find_Left_Node(int N); void Find_root(int left, int right, int root );
int main() { ?? ?int N=0, i=0, Data=0; ?? ?? ?scanf("%d", &N); ?? ?for(i=0;i<N;i++) scanf("%d", &num[i]); ?? ?sort(num,num+N); ?? ?Find_root(0, N-1, 0); ?? ?for(i=0;i<N;i++){ ?? ??? ?printf("%d", BST[i]); ?? ??? ?if(i!=N-1) printf(" "); ?? ?} ?? ? ?? ?return 0; }
int Find_Left_Node(int N)? ? ? ?//计算左子树结点个数 { ?? ?int i=0, L=0, floor=0, sum=1,tmp=0, number=0; ?? ?for(i=0;sum<=N+1;i++){ ?? ??? ?sum*=2; ?? ?} ?? ?floor=i; ?? ?sum = (int) pow(2,floor-1); ?? ?number=N-(sum-1); ?? ?tmp=(int) pow(2, floor-2); ?? ?L=number<tmp?number:tmp; ?? ?L=L+(sum-2)/2; ?? ? ?? ?return L; }
void Find_root(int left, int right, int root )? ? ? ?
//递归将大序列分成一堆子序列,分别求左子树结点个数 { ?? ?int length=right-left+1; ?? ?if(!length) return; ?? ?int L=Find_Left_Node(length); ?? ?BST[root]=num[left+L]; ?? ?int leftroot=2*root+1; ?? ?int rightroot=leftroot+1; ?? ?Find_root(left,left+L-1,leftroot); ?? ?Find_root(left+L+1,right,rightroot); }
|