首页 > 其他分享 >二叉树的递归遍历

二叉树的递归遍历

时间:2023-08-14 10:35:06浏览次数:42  
标签:lchild 遍历 return 递归 int Tree 二叉树 rchild

#include <stdio.h>
#include <stdlib.h>
 
typedef struct TNode{
    int data;
    struct TNode *lchild,*rchild;
}TreeNode,*Tree;

/*
在这段代码中,递归函数 `CreateTree` 在执行 `return` 语句后,会立即返回到调用它的上一层递归调用。
但是,整个递归过程并没有结束,仍然会继续执行后续的递归调用。
当 `CreateTree` 函数中执行 `return` 语句时,它会返回到上一层递归调用的位置,
并继续执行那个位置之后的代码。这是因为递归函数是通过函数调用栈来实现的,
每次递归调用都会在栈中创建一个新的帧,保存函数的局部变量和执行位置。
当递归函数执行完毕后,会从栈中弹出该帧,返回到上一层递归调用的位置,并继续执行。
因此,虽然在某一层递归调用中执行了 `return` 语句,但整个递归过程仍会继续执行,
直到所有的递归调用都执行完毕并返回。
*/ 

void CreateTree(Tree &T)
{
    int x;
    scanf("%d",&x);
    if(x==-1)
    {
        T=NULL;
        return;
    }
    else
    {
        T=(Tree)malloc(sizeof(TreeNode));
        T->data=x;
        printf("输入%d的左子节点:",x);
        CreateTree(T->lchild);
        printf("输入%d的右子节点:",x);
        CreateTree((T->rchild));
    }
}

//先序遍历二叉树(递归实现)
void PreOrderTree(Tree T)
{
    if (T==NULL)
    {
        return;
    }
    else
    {
        printf("%d ",T->data);
        PreOrderTree(T->lchild);
        PreOrderTree(T->rchild);
    }
}

//中序遍历二叉树(递归实现)
void MidOrderTree(Tree T)
{
    if(T==NULL)    
    {
        return;
    }
    else
    {
        MidOrderTree(T->lchild);
        printf("%d ",T->data);
        MidOrderTree(T->rchild);
    }
} 

//后序遍历二叉树(递归实现)
void LatOrderTree(Tree T)
{
    if(T==NULL)    
    {
        return;
    }
    else
    {
        LatOrderTree(T->lchild);
        LatOrderTree(T->rchild);
        printf("%d ",T->data);
    }
} 

int TreeDeep(Tree T)
{
    int deep=0;
    if(T)
    {
        int leftdeep=TreeDeep(T->lchild);
        int rightdeep=TreeDeep(T->rchild);
        deep=leftdeep>=rightdeep?leftdeep+1:rightdeep+1;
    }
    return deep;
} 

//二叉树的深度(递归实现) 
int TreeDeep(Tree T)
{
    int deep = 0;
    if (T != NULL)
    {
        int leftdeep = TreeDeep(T->lchild);
        int rightdeep = TreeDeep(T->rchild);
        deep = leftdeep >= rightdeep?leftdeep+1:rightdeep+1;
    }
    return deep;
}

/*
在这个函数中,`count`需要使用`static`修饰是因为它需要在递归调用中保持其值的持久性。
当函数被递归调用时,每次调用都会创建一个新的局部变量`count`,并且在递归返回时,它们的值会被销毁。
这意味着每次递归调用时,`count`的值都会被重置为0,无法正确地计算叶子节点的数量。
通过使用`static`修饰符,变量`count`的生命周期被扩展到整个程序的执行过程中,而不是局限于函数的单次调用。这样,每次递归调
用时,`count`的值会被保留下来,并能够正确地累加叶子节点的数量。
*/
//叶子节点个数(递归实现)
int LeafCount(Tree T)
{
    static int count;
    if (T != NULL)
    {
        if (T->lchild == NULL && T->rchild == NULL)
        {
            count++;
        }
        
        LeafCount(T->lchild);
        LeafCount(T->rchild);
    }
    
    return count;
}

//销毁二叉树(递归方法) 
void DestroyTree(Tree &T) {
    if (T) {
        DestroyTree(T->lchild);
        DestroyTree(T->rchild);
        free(T);
    }
}

int main()
{
    Tree T;
    CreateTree(T);
//    PreOrderTree(T);
//    MidOrderTree(T);    
    LatOrderTree(T);
    
    printf("\n");
    printf("树的深度为:%d\n",TreeDeep(T));
    printf("叶子结点的个数%d\n",LeafCount(T));
    return 0; 
} 

 

标签:lchild,遍历,return,递归,int,Tree,二叉树,rchild
From: https://www.cnblogs.com/simpleset/p/17627959.html

相关文章

  • 利用C语言递归函数解决求5的方法是什么
    利用C语言递归函数解决求5的方法是什么在C语言编程中,递归是一种非常有用的技术,它能够简化问题的解决过程并提高代码的复用性。本文将以求解数字5为例,介绍如何利用C语言递归函数来实现这一任务。9利用C语言递归函数解决求5的方法是什么首先,让我们明确问题的定义。求解数字5的方......
  • P9534 [YsOI2023] 广度优先遍历
    好题。首先考虑到对于任意的边的输入顺序,分层图是不会变的,即所有点到根的最短距离不变。那么分为两种边,分别为不同层的边相连,相同层的边相连。显然第二种边是无用的,我们将其放到最后输出即可。由于下层的决策会影响上层的决策而且不同层之间的边的顺序不会影响答案,所以我们按......
  • import.meta.globEager('./src/components/**/*.vue'); 遍历文件
    main.jsconstimportAll=(modules)=>{Object.keys(modules).forEach((key)=>{constcomponent=key.replace('/src/','@/').replace('.vue','');constcomponentName=key.split('/').slice......
  • 二叉树的层序遍历
    intfindBottomLeftValue(TreeNode*root){queue<TreeNode*>qu;if(root!=nullptr)qu.push(root);intsize=0;intresult=0;while(!qu.empty()){TreeNode*temp;size=qu.size();......
  • 数据结构与算法 --- 递归(二)
    引言上文数据结构与算法---递归(一)讲述了什么是递归算法,如何编写递归算法及如何写好递归算法,本文着重讲述一下如何避免递归过深导致的堆栈溢出问题。探究产生堆栈溢出的原因函数调用采用函数调用栈来保存当前“快照”(局部变量,返回地址等)。函数调用栈是内存中开辟的一块存储空......
  • 数据结构与算法 --- 递归(一)
    什么是递归?递归(Recursion)是一种解决问题的方法,它将问题分解为更小的子问题,并逐层解决这些子问题。递归算法的核心思想是:一个函数可以直接或间接地调用自身。通过这种自我调用,我们可以用简洁的代码来解决复杂问题。满足递归的条件一般来说,满足下面三个条件就可以使用递归:待......
  • 归并排序(递归)(NB)
    博客地址:https://www.cnblogs.com/zylyehuo/递归思路#_*_coding:utf-8_*_importrandomdefmerge(li,low,mid,high):i=lowj=mid+1ltmp=[]whilei<=midandj<=high:#只要左右两边都有数ifli[i]<li[j]:......
  • [代码随想录]Day16-二叉树part05
    题目:513.找树左下角的值思路:层序遍历是最好的选择了,先放右节点,再放左节点最后一个元素就是最左侧的节点。说白了层序遍历就是广度优先搜索BFS。代码:funcfindBottomLeftValue(root*TreeNode)int{node:=rootq:=[]*TreeNode{root}forlen(q)>0{......
  • p5两链表相交问题和二叉树
    (本文大多从杀戒之声处来,就想着自己方便看)两链表相交问题所谓相交,是指两链表有某一内存地址相同,则为相交,判断有环无环,哈希表(set),第一次相同(单向链表)快慢指针,快走2,慢走1,快慢指针第一次相遇后,将快指针返回头节点,慢指针不动,快改为走1,看快慢节点是否能相遇,有环则一定会在入环节......
  • 递归的进一步思考
    翻转二叉树:首先要想整体思路:翻转一个二叉树就是先将左子树和右子树翻转,然后对作用左子树翻转函数(对左子树中的所有左右结点翻转),对右子树进行翻转函数那么递归部分如下:swap(node->left,node->right);reverse(node->left);reverse(node->right);这里需要注意的是reverse......