现在的位置: 首页 > 综合 > 正文

浙大PAT 1064题 1064. Complete Binary Search Tree

2018年02月06日 ⁄ 综合 ⁄ 共 2194字 ⁄ 字号 评论关闭
#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;
}

抱歉!评论已关闭.