题目
一个无重复的非负整数序列,必定对应唯一的一棵形状为完全二叉树的二叉搜索树。本题就要求你输出这棵树的层序遍历序列。
代码
法一
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define N 100
void CreatCompleteTree(int left,int right,int root);
int findLeftLenght(int lenght);
void sort();
int data[N],T[N];
int n;
void main(){
int i;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&data[i]);
sort();
CreatCompleteTree(1,n,1);
for(i=1;i<=n;i++)
printf("%d ",T[i]);
system("pause");
}
void sort(){
int i,j,temp,flag;
for(i=1;i<n;i++){
flag=1;
for(j=1;j<=n-i;j++)
if(data[j]>data[j+1]){
flag=0;
temp=data[j];
data[j]=data[j+1];
data[j+1]=temp;
}
if(flag)
break;
}
}
void CreatCompleteTree(int left,int right,int root){
int len,leftlen;
int index,leftroot,rightroot;
len=right-left+1;
if(len==0)
return;
leftlen=findLeftLenght(len);
//printf("leftlen=%d \n",leftlen);
index=left+leftlen;
T[root]=data[index];
leftroot=2*root;
rightroot=2*root+1;
CreatCompleteTree(left,left+leftlen-1,leftroot);
CreatCompleteTree(left+leftlen+1,right,rightroot);
}
int findLeftLenght(int lenght){
int h,pre,real,len,leftlen;
h=floor( log((double)lenght)/log(2.0) );
//printf("h=%d\n",h);
pre=pow(2.0,h)-1;
leftlen=(pre-1)/2;
real=lenght-pre;
if(real > pow(2.0,h)/2)
real=pow(2.0,h)/2;
len=leftlen+real;
return len;
}
总结
以上做法属于暴力破解,把每个节点的所在数组中的位置都算出来,通过先将数字排序的方法,在根据搜索树的性质左子树的值都小于其根节点,算出根节点应该在的位置。(此方法比较难以理解,码起来涉及大量计算比较麻烦)。
法二
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define N 100
void InorderSearch(int root);
void sort();
int data[N],T[N];
int n,index=1;
void main(){
int i;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&data[i]);
sort();
InorderSearch(1);
for(i=1;i<=n;i++)
printf(" %d",T[i]);
system("pause");
}
void InorderSearch(int root){
if(root>n)
return ;
InorderSearch(root*2);
T[root]=data[index++];
InorderSearch(root*2+1);
}
void sort(){
int i,j,temp,flag;
for(i=1;i<n;i++){
flag=1;
for(j=1;j<=n-i;j++)
if(data[j]>data[j+1]){
flag=0;
temp=data[j];
data[j]=data[j+1];
data[j+1]=temp;
}
if(flag)
break;
}
}
总结
法二是因为运用了二叉搜索树的性质,其中序遍历一定是增序序列,然后采用增序遍历一遍二叉树,并给其赋值。