在写转换二叉树的swap()函数时发现和教材答案有所不同,为验证正确性写了如下代码测试
测试用的是一个三层满二叉树,共7个结点。给出先序和中序序列以创建二叉树。该树层次遍历顺序为ABCDEFG
BiTree PreInCreat(char A[],char B[],int l1,int h1,int l2,int h2){//创建二叉树
int i,llen,rlen;
BiTree root;
root=(BiNode*)malloc(sizeof(BiNode));
root->data=A[l1];
for(i=l2;B[i]!=root->data;i++);
llen=i-l2;
rlen=h2-i;
if(llen)
root->lchild=PreInCreat(A,B,l1+1,l1+llen,l2,l2+llen-1);
else
root->lchild=NULL;
if(rlen)
root->rchild=PreInCreat(A,B,h1-rlen+1,h1,h2-rlen+1,h2);
else
root->rchild=NULL;
return root;
}
BiTree swap(BiTree p){//交换二叉树
BiTree Temp;//Temp作为临时存储,存放即将被覆盖的lchild
if(p){
Temp=p->lchild;
p->lchild=swap(p->rchild);
p->rchild=swap(Temp);
return p;
}
else return NULL;
}
void InOrder(BiTree p){//中序遍历二叉树
if(p!=NULL){
InOrder(p->lchild);
cout<<p->data<<endl;
InOrder(p->rchild);
}
}
void main(){
BiTree T,T2;
char A[7]={'A','B','D','E','C','F','G'};
char B[7]={'D','B','E','A','F','C','G'};
T=PreInCreat(A,B,0,6,0,6);
InOrder(T);//检验二叉树创建是否成功
cout<<endl;
T2=swap(T);
InOrder(T2);//转换以后用层次遍历输出检验是否转换正确
system("pause");
}
↓程序文档//程序执行过程:
//此算法要给想创建的二叉树的先序和中序序列,并在数组中实现存储好,即main()中看见的A和B数组
//先用PreInCreat(A,B,0,6,0,6)函数将二叉树在内存中构建好,并把根结点返还给main中创建好的T
//整个函数用InOrder()函数输出二叉树内容以检验,现在把刚才构建好的T输出
//用T2承接swap转换好的新树
//InOrder(T2)输出新树,和旧树对验证对不对
//
//
发现的问题:
1.开始想用层次遍历来输出树中的数据,但随后发现层次遍历要借助队列,创建队列要用到InitQueue(),而这个并不是库函数要自己写,要写又要追加定义队列等等很烦,层次比较好理解但不代表好实现,因此后来改用中序遍历,其实并无差别,只是输出顺序不同一点,仍然可以检验swap的正确性
2.swap()函数原先以为可以返回void只换不返回,但照我的递归思路p->lchild=swap(p->rchild),是必须要有返回值的,因此定义swap的时候修改成了BiTree swap(BiTree p);课本上的方法就可以单纯换位置而不返回
3.生成二叉树时用的malloc()方法那个地方,教材上写的不完全,必须先:BiTree root;定义好结点指针之后才能:root=(BiNode*)malloc(sizeof(BiNode)),不然根本找不到root是什么赋值不上去。之前考虑的(BiTree)和(BiNode*)的确是一样的效果,目的就是获取刚开辟的那个空间的指针,而且这里思考了一下觉得这样应该也可行:BiNode root;root.data=A[l1];这样就不用malloc开辟空间,但之后就要用.访问,返回量也要改,其他函数也要改就没有实验