用递归思想解决二叉树的实际应用

本文详细介绍了如何使用递归思想解决二叉树相关的问题,包括二叉树的遍历、求叶子节点个数、计算深度及复制二叉树。通过实例分析递归的关键在于明确基本情况和递归情况,递归在二叉树问题中有着广泛的应用。
摘要由CSDN通过智能技术生成

递归的思想在于他将一件n的事情变成n-1的事情,反复如此即可得到一件关于1的事情,所以递归的关键有两点:1.当这件事为1的时候我们的具体操作;2.什么样的事情做n次与做n-1次是一样的。看下面的例子:

1.阶乘算法。

当我们求一个数n的阶乘时,首先按上面分析,这件事为1的时候我们的具体操作是--->1!=1.什么样的事情做n次与做n-1次相同--->当n*(n-1)的阶乘时,做n次与做n-1次相同。

因此算法如下:

int fac(int n)

{

int count;

if(n==1);

    count=1;

else

 count=n*fac(n-1);

return count;

}

2.hanoi 塔算法

说是有X,Y,Z三座塔,我们需要将n个从小到大依次放置的圆盘从X移动至Z,且大的盘不能在小的上面。

分析:这件事为1的时候我们怎么做----->move(X,1,Z);(意思是将X上的1个移动到Z)

什么样的事情做n次与做n-1次是相同的---->j将n-1个从X移动到Y,将第n个从X移动到Z:move(X,n,Z),再将n-1个从Y上移动到Z上:hanoi(n-1,Y,X,Z)。这就等同于hanoi(n,X,Y,Z).(意思为将n个圆盘通过Y这个媒介从X移动到Z)

因此算法如下:

void hanoi(int n,char X,char Y,char Z)

{

if(n==1)

move(X,1,Z);

else

{

hanoi(n-1,X,Z,Y);

move(X,n,Z);

hanoi(n-1,Y,X,Z);

}

因此递归的思想就是上面说的两点,在二叉树的一些应用中也很常见。

在前面的博文中,说到二叉树的递归遍历算法为:

访问根节点;访问左子树;访问右子树。由于左子树的遍历又是同原树的遍历是一样的路子,因此递归调用这个函数即可。

status ProOd(BiTree T,visit* e)

{

visit(....);

if(T)

{

if(visit(T->data))

   if(PreOd(T->lchild,visit))

       if(PreOd(T->rchild),visit)

           return OK;

    return ERROR

}

return NULL;

}

在二叉树的一些应用中也有着递归的思想。

1.求二叉树叶子节点的个数

分析:还是和上面的递归分析一样,当事情为1的时候怎么办--->节点数即为1;做什么样的事情n次与n-1次相同---->除开根节点,求其左子树与右子树的叶子节点相当于做n-1的过程。另外注意到这里的终止条件应该为找到了叶子节点(其左子树与右子树皆为空),然后开始计数。

算法如下:

int ListLeaf(BiTree T,int count)

{

if(T)

{

if(T->lchild==NULL&&T->rchild==NULL)

count++;

ListLeaf(T->lchild,count);

ListLeaf(T->rchild,count);

return count;

}

else return 0;

}

2.求二叉树的深度

分析:当这件事为1的时候--->二叉树深度为1,做什么样的事情n次与n-1次是一样的--->求二叉树的左子树与右子树的深度与求原树的深度是一样的。

关系为:二叉树的深度等于其左子树与右子树深度的较大值加上1.

算法如下:

int depth(BITree T)

{

if(T)

{

if(T->lchild==NULL&&T->rchild==NULL)

d=1;

else

{

dleft=depth(T->lchild);

dright=depth(T->rchild);

d=1+max(dleft,dright);

}

return d;

}

else return 0;

}

3.复制二叉树

二叉树的本质即是一个指向根节点的节点指针,其含有数据域,左子树与右子树。复制二叉树可以分解为复制根节点数据域,根节点左右子树。然后再从其左子树复制,左子树又可以当做一个根节点,再分析其左右子树与数据域。因此创建节点,复制节点应该是非常重要的一环。

创建一个根节点:

BiNode* rootnode(int item,char *lchild,char* rchild)

{

T=(BiNode*)malloc(sizeof(Node));

if(!T)  exit(1);

T->data=item;

T->lchild=newlchild;

T->rchild=newrchild;

return T;

}

BiNode *CopyTree(BiNode* T)

{

item=T->data;

if(T->lchild)

newlchild=CopyTree(T->lchild);

else return NULL;

if(T->rchild)

newrchild=CopyTree(T->rchild);

else return NULL;

newnode=rootnode(T->data,newlchild,newrchild);

return newnode;

}

方法可描述为将原来T的左子树复制给新左,将T的右子树复制给新右,将新左新右与数据按照节点函数结合在一起即可。

明日再介绍二叉树的建立过程。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值