二叉树的各算法的递归总结

在牛客的刷题过程中,总是遇到二叉树的遍历问题,做下总结,方便后面回顾。每次遇到二叉树的递归总是有点虚,似乎怕想不明白,但是其实就是几种情况,总结完就没问题。目前我看到的有,三种遍历的方式,求二叉树的深度,求二叉树的结点的个数,求叶子结点的个数,交换左右子树,销毁、复制一棵二叉树。随着牛客的做下来,慢慢在这个博客里面完善。
常用的是递归调用。其实可以把一整课二叉树看成是三个结点,每一个小的分支都是遵守同一种访问规律。

1. 三种遍历方式的总结:

首先是先序遍历,无非是先访问根节点,再访问左结点,最后访问右结点。那么访问的过程肯定是先访问正中间的根节点,再访问根节点的左结点,再访问第一个左结点的左结点。。。以此类推,直到没有左结点了,便访问最后一个左结点的右结点,由此往上,递推回去。感觉比较难讲清,看递归代码和自己画个图出来最明显。
void Preorder(BTNODE *T)
{
    if(T!= NULL){
        VISIT(T) #对T的操作  #根先操作
        Preorder(T->left)
        Preorder(T->right)
}

其次是中序遍历,中序遍历即先访问左结点,再访问根节点,最后访问右结点,对每一个二叉树的分支都是这么操作。与上述先序遍历差不多,只是左结点先通过VISIT(T)操作,每一个分支的根节点其实都是上一个分支的左结点或者是右结点,所以其实只是对左右结点进行操作,串联其所有的结点。

Void inorder(BTNode *t)
{
   if(t != NULL)
      inorder(t->left)   
      Visit(t)  #对结点t的操作  左结点先操作,再根,再右节点
      inorder(t->right)
}

最后是后序遍历,先访问左结点,再访问右结点,最后访问根节点。看代码区别很明显,也容易记住。

Void backorder(BTNNode *t){
   If(t!=NULL)
      backorder(t->left)
      backorder(t->right)
      Visit(t)
}

2.求二叉树的深度

def maxdepth(pRoot):
	if not pRoot:
		return 0
	return max(maxdepth(pRoot.left)+1, maxdepth(pRoot.right)+1)
 

3.求二叉树的结点个数

nodes = 0
def node(pRoot):
	if not pRoot:
		return 0
	nodes += 1
	node(pRoot.left)
	node(pRoot.right)
	return nodes

4.求二叉树的叶子结点个数

Status LeafCount(BiTree T){
    if(T){
        if(T->lchild==NULL&&T->rchild==NULL){
            Count++;
        }
        if(LeafCount(T->lchild))
            if(LeafCount(T->rchild))
            return 1;
    }
    else return 1;
}

# 第二种
nodes = 0
def node(pRoot):	
	if not pRoot:
 		nodes += 0.5
 		return nodes
 	node(pRoot.left)
 	node(pRoot.right) #一个叶子节点加了两次
	return nodes
	
 def leavenode(pRoot):
 	if not pRoot:
 		return 0
 	node(pRoot)
	return nodes
发布了12 篇原创文章 · 获赞 0 · 访问量 127

猜你喜欢

转载自blog.csdn.net/caihuanqia/article/details/104467497