#include<stdio.h>
#include<stdlib.h>
#include<queue>
using namespace std;
typedef struct TNode{
int value;
struct TNode* left;
struct TNode* right;
}Node;
int num[1008];
int cmp(const void *atmp,const void *btmp){
int* a=(int*)atmp;
int* b=(int*)btmp;
return *a-*b;
}
/*根据给定的层计算从0层到level总共的节点(1+2+4+...)*/
int calTotal(int level){
int i,j,total=0,tmp;
for(i=0;i<=level;i++){
tmp=1;
for(j=0;j<i;j++){
tmp=tmp*2;
}
total=total+tmp;
}
return total;
}
/*根据给定的节点总数计算树的层数,层数从0开始,返回的是树的深度-1(考虑到buildTree的计算方式)*/
int calLevel(int total){
int i,j,sum=0,tmp;
for(i=0;;i++){
tmp=1;
for(j=0;j<i;j++){
tmp=tmp*2;
}
sum=sum+tmp;
if(sum>=total) break;
}
return i-1;
}
/*
buildTree(int s,int e)其中s从0开始;
level为能构成的完全2叉搜索树的实际层数-1;
totalpre为前level(0,1,2....level)的总节点树;
totalcur为前level+1的总节点树;
想法是:前level上属于左子树的节点有totalpre/2。
用给定的节点数nodes=e-s+1,减去totalpre,那么剩下的节点肯定在下一层。
那么关键就是就算level+1层上有多少个节点属于左子树,而这点通过if语句就可以知道。
*/
Node* buildTree(int s,int e){
if(e-s<0){
return NULL;
}
if(e-s==0){
Node* node=(Node*)malloc(sizeof(Node));
node->value=num[s];
node->left=NULL;
node->right=NULL;
return node;
}
int level=calLevel(e-s+1);
int totalpre=calTotal(level);
int totalcur=calTotal(level+1);
int diff=totalcur-totalpre;
int nodes=e-s+1;
int leftChilds=totalpre/2;
if((nodes-totalpre)<diff/2)
leftChilds=leftChilds+(nodes-totalpre);
else
leftChilds=leftChilds+diff/2;
Node* node=(Node*)malloc(sizeof(Node));
node->value=num[s+leftChilds];
node->left=buildTree(s,s+leftChilds-1);
node->right=buildTree(s+leftChilds+1,e);
return node;
}
/*按照先序遍历打印树用作建树测试*/
void printTreePreOrder(Node* node){
if(node==NULL) return;
printf("%d ",node->value);
printTreePreOrder(node->left);
printTreePreOrder(node->right);
}
/*按照层次遍历打印树 */
void printTreeLevelOrder(Node* node){
queue<Node*> qu;
while(!qu.empty()){
qu.pop();
}
printf("%d",node->value);
if(node->left!=NULL) qu.push(node->left);
if(node->right!=NULL) qu.push(node->right);
while(!qu.empty()){
Node* tmp=qu.front();
qu.pop();
printf(" %d",tmp->value);
if(tmp->left!=NULL) qu.push(tmp->left);
if(tmp->right!=NULL) qu.push(tmp->right);
}
printf("\n");
}
/*回收树的内存*/
void Delloc(Node* node){
if(node==NULL) return;
Delloc(node->left);
Delloc(node->right);
free(node);
}
int main(){
int i,j,n;
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d",&num[i]);
}
qsort(num,n,sizeof(int),cmp);
Node* root=buildTree(0,n-1);
printTreeLevelOrder(root);
Delloc(root);
return 0;
}
浙大PAT 1064题 1064. Complete Binary Search Tree
最新推荐文章于 2021-05-09 22:51:09 发布