pat 1064

构建CBT(completed binary tree),然后层序遍历
先排序,然后根据CBT两边节点数的规定,求出左子树的节点数,从而找出根,递归

#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<queue>
using namespace std;

struct bst{
    int num;
    struct bst *left, *right;
};
struct bst* BuildTree(int a[], int begin, int end,int level){
    if (begin > end)
        return NULL;
    struct bst *node = new struct bst;
    if (!level){
        node->num = a[begin];
        node->left = node->right = NULL;
        return node;
    }
    else{
        int n = end - begin + 1;
        int index  = n - (int)pow(2,level) + 1;
        if (index <= (int)pow(2, level - 1))
            index += (int)pow(2, level - 1) - 1;
        else index = (int)pow(2, level - 1) + (int)pow(2, level - 1) - 1;
        node->num = a[begin + index];
        node->left = BuildTree(a, begin, begin + index - 1, level - 1);
        node->right = BuildTree(a , begin + index + 1, end, level - 1);
        return node;
    }
}
queue<struct bst> q;
void LevelTravsal(struct bst *t){
    if (!t)
        return;
    printf("%d", t->num);
    if (t->left)
        q.push(*t->left);
    if (t->right)
        q.push(*t->right);
    struct bst node;
    while (q.size()){
        node = q.front();
        q.pop();
        printf(" %d", node.num);
        if (node.left)
            q.push(*node.left);
        if (node.right)
            q.push(*node.right);
    }
    putchar('\n');
}

void preorder(struct bst *t){
    if (t)
        printf("%d\n", t->num);
    else return;
    if (t->left)
        preorder(t->left);
    if (t->right)
        preorder(t->right);
}
int main(){
    int n;
    freopen("1.in", "r", stdin);
    scanf("%d", &n);
    int *a = new int[n];
    int i;
    for (i = 0; i < n; i++)
        scanf("%d", &a[i]);
    sort(a, a + n);
    int level = 0;
    int num = 1,size = n;
    while (size > num){
        size -= num;
        level++;
        num *= 2;
    }
    struct bst *t = BuildTree(a, 0, n - 1,level);
    LevelTravsal(t);
    //preorder(t);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值