树和二叉树:二叉树的构造
回顾
同一棵二叉树(假设每个节点值唯一)具有唯一先序序列,中序序列和后序序列
但不同的二叉树可能具有相同的先序序列,中序序列或后序序列
例如:
以下命题成立否?
- 同时给定一棵二叉树的先序序列和中序序列就能唯一确定这棵二叉树。(正确)
- 同时给定一棵二叉树的中序序列和后序序列就能唯一确定这棵二叉树。(正确)
- 同时给定一棵二叉树的先序序列和后序序列就能唯一确定这棵二叉树。(错误)
定理1: 任何n(n>0)个不同节点的二叉树,都可由它的中序序列和先序序列唯一地确定
由先序和中序序列构造二叉树示例的演示
例如,已知先序序列为ABDGCEF,中序序列为DGBAECF,则构造二叉树的过程如下所示。
由上述定理得到以下构造二叉树的算法:
BTNode *CreateBT1(char *pre,char *in,int n) {
BTNode *s;
char *p;
int k;
if(n<=0) return NULL;
s=(BTNode *)malloc(sizeof(BTNode)); //创建根节点
s->data=*pre;
for(p=in;i<in+n;p++) //在in中找为*pre的位置k
if(*p==*pre)
break;
k=p-in;
s->lchild=CreateBT1(pre+1,in,k); //构造左子树
s->rchild=CreateBT1(pre+k+1,p+1,n-k-1); //构造右子树
return s;
} //先序遍历的思路
定理2: 任何n(n>0)个不同节点的二叉树,都可由它的中序序列和后序序列唯一地确定
例如,已知中序序列为DGBAECF,后序序列为GDBEFCA。对应的构造二叉树的过程如下所示
由上述定理得到以下构造二叉树的算法:
BTNode *CreateBT2(char *post,char *in,int n) {
BTNode *b;
char r,*p;
int k;
if(n<=0)
return NULL;
r=*(post+n-1); //根节点值
b=(BTNode *)malloc(sizeof(BTNode)); //创建二叉树节点*b
b->data=r;
for(p=in;p<in+n;p++) //在in中查找根节点
if(*p==r)
break;
k=p-in; //k为根节点在in中的下标
b->lchild=CreateBT2(post,in,k); //递归构造左子树
b->rchild=CreateBT2(post+k,p+1,n-k-1); //递归构造右子树
return b; //先序遍历的思路
}
例题:
对应的递归算法如下:
BTNode *trans1(SqBTree a,int i) {
BTNode *b;
if(i>MaxSize)
return NULL;
if(a[i]=='#')
return NULL; //当节点不存在时返回NULL
b=(BTNode *)malloc(sizeof(BTNode)); //创建根节点
b->data=a[i];
b->lchild=trans1(a,2*i); //递归创建左子树
b->rchild=trans1(a,2*i+1); //递归创建右子树
return(b); //返回根节点
} //先序遍历的思路
对应的递归算法如下:
void *trans2(BTNode *b,SqBTree a,int i) {
if(b!=NULL) {
a[i]=b->data; //创建根节点
trans2(b->lchild,a,2*i); //递归创建左子树
trans2(b->rchild,a,2*i+1); //递归创建右子树
}
} //先序遍历的思路