二叉树(二)——叶子节点数、节点数、深度、复制二叉树

二叉树遍历的应用

二叉树的遍历有四个应用:

  1. 求二叉树深度
  2. 求二叉树所有节点
  3. 求二叉树的叶子结点
  4. 复制二叉树
二叉树的深度

深度:根节点到叶子节点的最长路径(边的个数)

求二叉树的深度->左子树的深度与右子数的深度,最大的哪个

int calculate_depth(pBT pB)     //计算深度
{
    int m, n;
    if(pB==NULL)
    {
        return 0;
    }
    else
    {
        m = calculate_depth(pB->left);  //计算左子树深度
        n = calculate_depth(pB->right); //计算右子树深度
        if(m>=n)                        //比较哪个深度更大,返回大的深度
        {
            return m + 1;
        }
        return n + 1;
    }
}
求二叉树的所有节点

二叉树的所有节点:根节点+左子树的结点+右子树的结点

int calculate_sum(pBT pB)
{
    int m,n;
    if(pB==NULL)
    {
        return 0;
    }else
    {
        m = calculate_sum(pB->left);        //记录左子树的结点数
        n = calculate_sum(pB->right);       //记录右子树的结点数
        return m + n + 1;					//还要加上根节点
    }
}
求二叉树的叶子结点

叶子节点:左右孩子指针为NULL

int calculate_sumleaf(pBT pB)
{
    int m, n;
    if(pB==NULL)        //如果为空,证明是空树,叶子节点为0
    {
        return 0;
    }
    if(pB->left==NULL&&pB->right==NULL)     //左指针和右指针为NULL,说明是叶子节点
    {
        return 1;
    }
    else
    {
        m = calculate_sumleaf(pB->left);    //计算左子树叶子结点
        n = calculate_sumleaf(pB->right);   //计算右子树叶子节点
        return m + n;                       //左子树和右子数叶子节点相加
    }
}
复制二叉树

采用的是前序遍历的方法来复制二叉树,先复制根节点再复制左子树再复制右子数

pBT copy_tree(pBT pB)
{
    pBT pB1;
    if(pB==NULL)
    {
        pB1 = NULL;
        return ;
    }else
    {
        pB1 = (pBT)malloc(sizeof(BT));
        pB1->data = pB->data;               //先复制根节点
        pB1->left = copy_tree(pB->left);     //再复制左子树
        pB1->right = copy_tree(pB->right);   //然后复制右子树

    }
    return pB1;
}
完整代码
#include <stdio.h>
#include <windows.h>
#include <malloc.h>
#include <stdbool.h>
/*二叉树的函数和数据结构*/
typedef struct binary_tree
{
    int data;
    struct binary_tree *left, *right;

} BT, *pBT;
void create_tree(pBT *);
int calculate_depth(pBT);
int calculate_sum(pBT);
pBT copy_tree(pBT);
void Pretraverse_tree(pBT);
int main()
{
    pBT pB;
    pBT pB1;
    printf("please input the information(AB#C##D##):");
    create_tree(&pB);
    printf("the depth of the tree:%d\n", calculate_depth(pB));
    printf("the sum of the tree:%d\n", calculate_sum(pB));
    printf("the sum of the tree leaf:%d\n", calculate_sumleaf(pB));
    pB1=copy_tree(pB);
    Pretraverse_tree(pB1);
}
void create_tree(pBT *T)        //建立一个二叉树
{
    char c;
    scanf("%c", &c);
    if (c == '#')
    {
        *T = NULL;
    }
    else
    {
        (*T) = (pBT)malloc(sizeof(BT));
        (*T)->data = c;
        create_tree(&(*T)->left); 
        create_tree(&(*T)->right);
    }
}
void Pretraverse_tree(pBT pB)   //二叉树的前序遍历
{
    if(pB==NULL)
    {
        return;
    }
    else
    {
    printf("%c", pB->data);
    Pretraverse_tree(pB->left);
    Pretraverse_tree(pB->right);
    }
}
int calculate_depth(pBT pB)     //计算深度
{
    int m, n;
    if(pB==NULL)
    {
        return 0;
    }
    else
    {
        m = calculate_depth(pB->left);  //计算左子树深度
        n = calculate_depth(pB->right); //计算右子树深度
        if(m>=n)                        //比较哪个深度更大,返回大的深度
        {
            return m + 1;
        }
        return n + 1;
    }
}
int calculate_sum(pBT pB)
{
    int m,n;
    if(pB==NULL)
    {
        return 0;
    }else
    {
        m = calculate_sum(pB->left);        //记录左子树的结点数
        n = calculate_sum(pB->right);       //记录右子树的结点数
        return m + n + 1;
    }
}
int calculate_sumleaf(pBT pB)
{
    int m, n;
    if(pB==NULL)        //如果为空,证明是空树,叶子节点为0
    {
        return 0;
    }
    if(pB->left==NULL&&pB->right==NULL)     //左指针和右指针为NULL,说明是叶子节点
    {
        return 1;
    }
    else
    {
        m = calculate_sumleaf(pB->left);    //计算左子树叶子结点
        n = calculate_sumleaf(pB->right);   //计算右子树叶子节点
        return m + n;                       //左子树和右子数叶子节点相加
    }
}
pBT copy_tree(pBT pB)
{
    pBT pB1;
    if(pB==NULL)
    {
        pB1 = NULL;
        return ;
    }else
    {
        pB1 = (pBT)malloc(sizeof(BT));
        pB1->data = pB->data;               //先复制根节点
        pB1->left = copy_tree(pB->left);     //再复制左子树
        pB1->right = copy_tree(pB->right);   //然后复制右子树

    }
    return pB1;
}

遍历的方法是前序遍历.所以复制输出的是前序遍历的顺序(即输入顺序)
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值