求深度
深度的定义已经在之前给出了,不做赘述
int depth(btree *bt)//求深度
{
int ldepth,rdepth;
if(!bt)
return 0;
else
{
ldepth=depth(bt->lchild);
rdepth=depth(bt->rchild);
if(ldepth>rdepth)
return ldepth+1;//加一是根节点
else
return rdepth+1;
}
}
因为有递归的性质,所以我们只需要比较根节点的左右子树的高度,取较大值加一(别忘了根节点)返回就行了,对于左子树或者是右子树,调用相同的函数,不断比较直到遇到叶子节点返回0,作为递归函数的退出。
复制二叉树
(这里面的复制可不是用一个新的指针指向根节点就完了的!是要一个个结点都创建后连接成一个新的二叉树。。。)
btree* Copy(btree* bt)//二叉树复制
{
btree* temp=NULL;
if(bt)
{
temp=(btree*)malloc(sizeof(btree));
temp->data=bt->data;
temp->lchild=Copy(bt->lchild);
temp->rchild=Copy(bt->rchild);
}
return temp;
}
仍然为递归的思想,对每一个结点都调用函数,并接下来处理子树。
二叉树的等价、相似判定
先声明一下什么的等价和相似:
等价就是两棵二叉树存储信息完全相同(包括结构相同、每一个数值域相同)
而等等价会弱一点,只需要结构相同
int if_equal(btree* bta,btree* btb)//判断二叉树相等
{
int x=0;
btree* a=bta,*b=btb;
if(!bta&&!btb)
return 1;
else
{
if(a&&b)
if(a->data==b->data)//少了这个是等价
if(if_equal(a->lchild,b->rchild))
x=if_equal(a->rchild,b->rchild);
}
return x;
}
将有注释行删掉,就是相似的条件了。
和之前相同,递归的思路:如果左子树相同,看一下右子树就行了,相同返回1,否则为0。
格式输出
将二叉树按照Key(LT,RT)的形式输出,key为根节点的数值域,括号前面是左子树,后面右子树。
void print(btree* bt)//Key(LT,RT)格式输出
{
cout<<bt->data;
if(bt->lchild||bt->rchild)
cout << "(";
if(bt->lchild)
{
print(bt->lchild);
if(bt->rchild)
{
cout<< ",";
print(bt->rchild);
}
}
if(bt->lchild||bt->rchild)
cout << ")";
}
空结点直接输出,如果只有左孩子就不输出逗号,如果都有就要输出逗号,右括号看左括号有没有。
判断满二叉树
int full(btree *b)//判断是否为满二叉树
{
if(b!=NULL)
{
if((b->lchild==NULL)&&(b->rchild==NULL))//空结点
return 1;
else if((b->lchild==NULL)||(b->rchild==NULL))
return 0;
else
return(full(b->lchild)&&full(b->rchild));//如果两个孩子都有,还要看子树的情况
}
}
也是递归的思想,不做过多的讲述
将一个指针二叉树存储到数组中
void create(btree* t,char a[],int i)//二叉链表存入数组
{
if(t)
{
a[i]=t->data;
create(t->lchild, a, 2*i);
create(t->rchild, a, 2*i+1);
}
else
a[i]='#';
}
这个没什么需要说明的,就是按照最开始的第五条性质:
下面是主函数的一部分
int length=pow(2,depth(bt)+1);
char a[length]={0};//数组存储(按满二叉树存储,空的都置为‘#’)
create(bt,a,1);
for(int i=1;i<length;i++)
{
if(a[i])
cout<< a[i]<< " ";
}
有一个小细节,就是将层数加一,这是为了防止在处理叶子结点将数组下标越界了。
相比确定的补成满二叉树或者完全二叉树,这种方法更简单一些。
不是和理论上一样的特别理想,不过简单实用一些。