04-树6 Complete Binary Search Tree(30 point(s))

题目位置
分析:
题目要求为:完美二叉树 + 搜索树 可以唯一确定一颗 二叉树。
因 涉及到完美二叉树 那题目就简单的 多的多了。
我们知道 搜索树的由来 是由 二分查找法 步骤图 而来,二分查找法的要求 是 必须用数组 存储 有序字符,我们还知道 完美二叉树也是可以通过数组进行存储,这个题说到这里,已经可以迎刃而解了。
完美二叉树 有 如下特点供我们使用:
1、N个结点 最大树高为 :log2 n 取整 + 1
2、给定结点 后 可知 左右子树结点个数。
左:
2 的 (MaxHeight(N)-2 )次方 – 1
如果【N – {2 的 (MaxHeight(N)-2 )次方 – 1 }*2-1 >= 2 的 (MaxHeight(N)-2)次方】
则+2 的 (MaxHeight(N)-2)次方
否则 + N – {2 的 (MaxHeight(N)-2 )次方 – 1 }*2 – 1
左
右:N-左 得右
二叉搜索树 有 如下特点供我们使用
1、因为 从大到小 根据一定规则排序,如果知道 左右子树结点个数,即可唯一确定这个根结点的数值。
故根据如上 特性 即可解决此题。
level traversal 利用queue 解决。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct BinTree *Tree;
struct BinTree{
    int data;
    Tree left;
    Tree right;
};
int MaxHeight(int N);
Tree CBST(int *a,int Left,int right);
int LeftNodeNum(int N);
int compare(const void *elem1,const void *elem2);
Tree deleteQue(Tree *queue,int *front,int *rear,int N);
void insertQue(Tree *queue,int *rear,Tree T,int N);
int main(){
    int N;
    scanf("%d",&N);
    int i,j;
    int a[N];
    for(i=0;i<N;i++){
        scanf("%d",&a[i]);
    }
    qsort(a,N,sizeof(a[0]),compare);
//    int b = LeftNodeNum();
//    printf("%d",b);
    Tree T;
    T=CBST(a,1,N);
    Tree queue[N];
    int rear  =-1;
    int front =-1;
    Tree B;
    insertQue(queue,&rear,T,N);
    i=0;
    while(1){
     B = deleteQue(queue,&front,&rear,N);
     i++;
     if(!B)break;
     printf("%d",B->data);
     if(i!=N)printf(" ");
     if(B->left)insertQue(queue,&rear,B->left,N);
     if(B->right)insertQue(queue,&rear,B->right,N);
    }
}
Tree deleteQue(Tree *queue,int *front,int *rear,int N){
if(*rear==*front)return NULL;
*front = (*front)%N +1;
Tree B = queue[*front];
return B;
}
void insertQue(Tree *queue,int *rear,Tree T,int N){
*rear = (*rear)%N+1;
queue[*rear]=T;
return;
}
Tree CBST(int *a,int Left,int right){
    Tree T=(Tree)malloc(sizeof(struct BinTree));
    T->left=NULL;
    T->right=NULL;
    if(Left == right){T->data = a[Left-1];return T;}
    int node = Left+LeftNodeNum(right-Left+1);
    T->data=a[node-1];
    if(node == right){T->left = CBST(a,Left,node-1),T->right=NULL;return T;}
    T->left=CBST(a,Left,node-1);
    T->right=CBST(a,node+1,right);
    return T;
}
int LeftNodeNum(int N){
    if(N==1)return 0;
    int leftCmpTreeNum = (int)pow(2,MaxHeight(N)-2) -1;
    if(N-(leftCmpTreeNum)*2-1>=leftCmpTreeNum+1)
        leftCmpTreeNum = leftCmpTreeNum+leftCmpTreeNum+1;
    else leftCmpTreeNum =leftCmpTreeNum +N-(leftCmpTreeNum)*2-1;
    return leftCmpTreeNum;
}
int MaxHeight(int N){
    int i,j;
    for(i=0,j=0;i<N;i++){
        i = i*2;
        j++;
    }
    return j;
}
int compare(const void *elem1,const void *elem2){
    return *(int*)elem1 - *(int*)elem2;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值