要求:给出一组数据,根据这组数据创建完全二叉树。
首先,我们知道,数组下标的范围是0到n-1,而在树中编号是从1开始的,下标的范围是1到n;
根据二叉树的性质(将一个完全二叉树按照从上到下,从左到右进行编号,其编号为i的节点,如果满足2*i<=n,则说明编号为i的节点有左孩子,否则没有,如果满足2*i+1<=n,则说明编号为i的节点有右孩子,否则没有)可知
2*i<=n
2*i+1<=n
该性质是对树的编号(1~n)成立的,而数组的下标是从0到n-1,将对应下标都减1可知,对于数组0~n-1来说,
2*i-1<=n-1
2*i<=n-1是成立的。
进一步来看一下得到的两个新规律是否能直接用,对于2*i-1<=n-1 来说,当i=0时 ,2*i-1=-1,而2*i-1对应的是什么呢?是编号i的节点的左孩子的编号,显然没有编号为-1的节点,那我们试一试将2*i-1+1呢,当i=0时 ,2*i-1=0,编号为0的节点对应的左孩子显然不能是本身,于是在此基础上再加一,得到结论:
2*i-1+2=2*i+1<=n-1
2*i+2=2*i+2<=n-1
接下来就是具体实现的思路了:
malloc出一块连续的空间,每一块空间放的都是一个BinaryTree结构体
1 //根据数组创建完全二叉树 2 #include<iostream> 3 #include<stdio.h> 4 using namespace std; 5 typedef struct Tree 6 { 7 int value; 8 struct Tree*left; 9 struct Tree*right; 10 11 }BinaryTree; 12 BinaryTree* create(int a[],int n) 13 { 14 BinaryTree *ptree=(BinaryTree*)malloc(sizeof(BinaryTree )*n); 15 int i; 16 for(i=0;i<n;i++) 17 { 18 ptree[i].value=a[i];//数组a只起到一个赋值的作用 19 ptree[i].left=NULL; 20 ptree[i].right=NULL; 21 } 22 for(i=0;i<=n/2-1;i++)//原来的父亲节点范围为1~n/2,现在0~n/2-1,所以注意n/2要取到等 23 { 24 if(2*i+1<=n-1) 25 ptree[i].left=&ptree[2*i+1];//把第2*i+1个结点的地址赋给左孩子 26 if(2*i+2<=n-1) 27 ptree[i].right=&ptree[2*i+2]; 28 } 29 return ptree; 30 } 31 void preorder(BinaryTree* t) 32 { 33 if(t==NULL) return ; 34 printf("%d ",t->value); 35 preorder(t->left); 36 preorder(t->right); 37 } 38 int main() 39 { 40 int a[]={3,4,5,8,9,10}; 41 BinaryTree *root=NULL; 42 root=create(a,sizeof(a)/sizeof(a[0])); 43 44 preorder(root); 45 return 0; 46 }
-