以顺序数列建立一个完全二叉搜索树
本程序在code::blocks 17.12上运行正常
#include <stdio.h>
#include <stdlib.h>
//这里为了省事 把两个数组直接写成静态变量了。可以写成一个结构体并传参
int tree[10];//将被填充的数组形式的完全二叉树
int array[11]={1,2,3,4,5,6,7,8,9,10};//需要的数列(顺序排列)
int i=1;//静态变量:tree的编号,从1开始计,i*2 i*2+1分别表示左儿子右儿子
void CompleteTree(int start,int len,int leftorright){//三个变量分别表示传入的数组起点、长度、是左儿子还是右儿子
int find=CalculationScale(len);//左子树的规模
if(leftorright==0){//是上一个(i)的左儿子
i=i*2;
tree[i]=array[start+find];
printf("%d是左子节点\n",array[start+find]);
}else if(leftorright==1){//是上一个(i)的右儿子
i=i*2+1;
tree[i]=array[start+find];
printf("%d是右子节点\n",array[start+find]);
}else if(leftorright==-1){//根节点(只有第一次)
tree[i]=array[start+find];
printf("%d是根节点\n",array[start+find]);
}
int len1=find;
int start1=start;
int len2=len-len1-1;
int start2=start+find+1;
if(len1!=0){
CompleteTree(start1,len1,0);//成为左儿子递归
}
if(len2!=0){
CompleteTree(start2,len2,1);//成为右儿子递归
}
if(len1==0&&len2==0){
printf("叶节点\n");
i=i/2;//i返回其父节点
return;
}
i=i/2;//函数结束返回其父节点
return;
}
///计算左子树规模
int CalculationScale(int size){
if(size==1||size==0){
return 0;
}
int i=1;
int res=2;
for(;;i++){
if(power(2,i)>size){
i--;
break;
}
}
printf("i=%d\n",i);
int j=i-1;
while(j--){
res=res*2+1;
}
printf("res=%d\n",res);
if(size>=res){
return power(2,i)-1;
}else{
return power(2,i-1)+size-power(2,i);
}
}
///以完全二叉树的形式输出动态数组
void Output(int* H,int size){
int limt=1;
int j=1;//总的计数值(1~size)
int i=1;//每层树的计数值(1~limt)
for(;;){
for(;i<=limt;i++,j++){
printf("[%d]%d ",j,H[j]);
if(j==size){
return;
}
}
i=1;
printf("\n\n");
limt=limt*2;
}
}
///num^i
int power(int num,int i){
int res=1;
while(i--){
res=res*num;
}
return res;
}
int main()
{
//printf("%d",CalculationScale(1));
CompleteTree(0,10,-1);
Output(tree,10);
}