04-树6 Complete Binary Search Tree (30 分)------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

        这题的思路其实非常简单,问题在于如何简洁的实现。

        思路其实是:将输入的一堆数据按照升序排列好之后,计算得到左子树的结点个数后,因为所有左子树结点值都小于根结点,所有右子树结点值都大于或等于根结点,那么在排好的序列中左子树个数+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);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值