1064 Complete Binary Search Tree (BST binary search using the output sequence preorder traversal)

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

 

Reference Gangster blog: https://blog.csdn.net/richenyunqi/article/details/78868563

This topic and ideas

Method 1: Use the full nature of the binary tree search 

n is the number of junction points

1. First input n sorted values ​​obtained in nodes arranged in order,

2. rounding (Floor () is rounded down, ceil is rounded up) by log (n + 1) is removed down to give the final layer height h eg: n = the height of the node 7 is 3 (because only a value of the root node is required to remove the last log n + 1 layer height)

 3. The number of nodes to obtain a final layer: n - (pow (2, h) - 1); (there may be only a left node, there is a right node)

 4. In the test arrangement order in the sample 1: 0123456789 long as we know the number of the left node NUM; by ( left (left most node preorder) NUM + can be determined after the root node) and then continue recursively find the root to the left subtree, the right subtree, a set of root index record index sequence output convenient

So temp2 = (pow (2, h) - 1) / 2

5. How to determine the key number of the left subtree of nodes: In this case the maximum number of nodes obtained temp2 last layer can be stored in the left subtree (the last half of the maximum capacity capable of storing one's) by min (temp2, n - (pow (2, h) - 1)) to give the left subtree of the last layer elements can be stored in this case, temp2 -1 can be the last layer number of the left subtree is removed: and therefore the number of sum nodes to the left : sum = temp2 - 1 + min (temp2, n - (pow (2, h) - 1))                                        

 

Specific code

#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
int n;
vector<int> in,level;
void levelOrder(int start, int end, int index){
	if(start > end) return;
    int sum = end - start + 1;
	int height = (int)floor(log((sum) + 1) / log(2)); //还没强转 log在cmath库中 
	int temp1 = sum - (int)(pow(2, height) - 1);  //最后一层的结点数量 
	int temp2 = pow(2, height) / 2; 	   //最后一层能够容纳的最大结点数量的一半 
	temp1 = min(temp1, temp2);         //取最小是因为temp1可能包含右结点,现在只需要算出左结点
	temp1 = start + temp1 + temp2 - 1;         //此时左子树结点总数为(temp1 + temp2 - 1) 同时加上start(left)就是中序遍历中根结点的下标
	level[index] = in[temp1];
	levelOrder(start, temp1 - 1, 2 * index + 1);
	levelOrder(temp1 + 1, end, 2 * index + 2);
}	
int main(){
	scanf("%d", &n);
	in.resize(n);    //在全局遍历中 用(n)也不能scanf输入 这里注意 只有用resize容器具有具体长度时 才能用scanf赋值 
	level.resize(n);
	for(int i = 0; i < n; i++){
		scanf("%d", &in[i]);
	}
	sort(in.begin(), in.end());
	levelOrder(0, n-1, 0);	
	for(auto i = 0; i < n; i++){
		if(i != 0) printf(" ");
		printf("%d", level[i]);
	}
	return 0;
}

Method Two:

               One method found by sequentially each root node of each node point subscript index into the array level,

               More convenient way is by direct sequence preorder traversal of the each element in the array is not added to the level required to locate each root preorder number determined by the height, the left node found

    

              Specific code:

           

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int n,position=0;
vector<int> level, in;
void levelOrder(int index){
	if(index > n-1) return;      //注意这里是n-1 因为根节点的下标是0 那么最后一个结点的下标为n-1 
	levelOrder(index * 2 + 1);   // 完全二叉搜索树中中序遍历中 第一个结点会是最左边的结点 
	level[index] = in[position++];
	levelOrder(index * 2 + 2);
}
int main(){
	scanf("%d", &n);
	level.resize(n);in.resize(n);
	for(int i = 0; i < n; i++){
		scanf("%d", &in[i]);
	}
	sort(in.begin(),in.end());
	levelOrder(0);
	for(int i = 0; i < n; i++){
		if(i != 0) printf(" ");
		printf("%d", level[i]);
	}
	return 0;
}

 

Guess you like

Origin blog.csdn.net/qq_41698081/article/details/91046576