二叉树的一些递归小问题——求深度、复制、等价、相似、格式输出、判满二叉树、存储格式转换(二叉链表->数组)

求深度

深度的定义已经在之前给出了,不做赘述

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]<< " ";
    }

有一个小细节,就是将层数加一,这是为了防止在处理叶子结点将数组下标越界了。
相比确定的补成满二叉树或者完全二叉树,这种方法更简单一些。
不是和理论上一样的特别理想,不过简单实用一些。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值