求二叉树中的结点个数、叶子结点个数、某结点层次和二叉树宽度

本文介绍了一个程序,用于实现二叉树的多种遍历算法,包括先序、中序、后序和层次遍历。通过递归算法,程序能够计算二叉树的结点个数、叶子结点个数,查找指定结点的层次,并求得树的最大宽度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目的:掌握二叉树遍历算法的应用,熟练使用先序、中序、后序3种递归遍历算法和层次遍历算法进行二叉树的问题求解。

内容:编写一个程序exp7-6.cpp实现以下功能,并对图7.33所示的二叉树进行验证。

(1)输出二叉树b的结点个数。

(2)输出二叉树b的叶子结点个数。

(3)求二叉树b中指定结点值(假设所有节点值不同)的结点层次。

(4)利用层次遍历求二叉树b的宽度。

代码如下:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <algorithm>
using namespace std;
const int MaxSize=10000;
typedef int ElemType;
typedef struct node
{
    ElemType data;
    struct node * lchild;
    struct node * rchild;
}BTNode;

void CreateBTree(BTNode * &b,string str)//创建二叉树
{
    BTNode *St[MaxSize],*p;
    int top=-1,k,j=0;
    char ch;
    p=NULL;
    b=NULL;
    ch=str[j];
    while(ch!='\0')
    {
        switch(ch)
        {
            case '(':top++;St[top]=p;k=1;break;
            case ')':top--;break;
            case ',':k=2;break;
            default:p=(BTNode *)malloc(sizeof(BTNode));
                    p->data=ch;
                    p->lchild=p->rchild=NULL;
                    if(b==NULL)
                        b=p;
                    else
                    {
                        switch(k)
                        {
                            case 1:St[top]->lchild=p;break;
                            case 2:St[top]->rchild=p;break;
                        }
                    }
        }
        j++;
        ch=str[j];
    }
}
void PreOrder(BTNode *b)//先序遍历递归算法
{
    if(b!=NULL)
    {
        printf("%c",b->data);//访问根节点
        PreOrder(b->lchild);//先序遍历左子树
        PreOrder(b->rchild);//先序遍历右子树
    }
}
void InOrder(BTNode *b)//中序遍历递归算法
{
    if(b!=NULL)
    {
        InOrder(b->lchild);//中序遍历左子树
        printf("%c",b->data);//访问根节点
        InOrder(b->rchild);//中序遍历右子树
    }
}
void PostOrder(BTNode *b)//后序遍历递归算法
{
    if(b!=NULL)
    {
        PostOrder(b->lchild);//后序遍历左子树
        PostOrder(b->rchild);//后序遍历右子树
        printf("%c",b->data);//访问根节点
    }
}
int Nodes(BTNode *b)//结点个数
{
    if(b==NULL) return 0;
    else return Nodes(b->lchild)+Nodes(b->rchild)+1;
}
int Leaves(BTNode *b)//叶子结点个数
{
    static int cont=0;
    if(b!=NULL)
    {
        if(b->lchild==NULL&&b->rchild==NULL)
            cont++;
        Leaves(b->lchild);
        Leaves(b->rchild);
    }
    return cont;
}
int Level(BTNode *b,ElemType x,int h)//结点所在层次
{
    int ans;
    if(b==NULL) return 0;
    else if(b->data==x) return h;
    else{
        ans=Level(b->lchild,x,h+1);
        if(ans!=0) return ans;
        else return Level(b->rchild,x,h+1);
    }
}
int getWidth(BTNode *b)//最大宽度
{
    if(b==NULL) return 0;
    int width=0;
    queue <BTNode *> q;
    q.push(b);
    {
        while(true)
        {
            int len=q.size();
            if(len==0) break;
            width=max(width,len);
            while(len)
            {
                BTNode* t=q.front();
                q.pop();
                len--;
                if(t->lchild!=NULL) q.push(t->lchild);
                if(t->rchild!=NULL) q.push(t->rchild);
            }
        }
    }
    return width;
}
int main()
{
    string str ="A(B(D,E(H(J,K(L,M(,N))),)),C(F,G(,I)))";
    BTNode *b;
    CreateBTree(b,str);
    cout<<"该二叉树的括号表示法为:"<<str<<endl;
    int nodes=Nodes(b);
    printf("结点个数:%d\n",nodes);
    int leaves=Leaves(b);
    printf("叶子结点个数:%d\n",leaves);
    for(int i=0;i<str.size();i++)
    {
        if(str[i]>='A'&&str[i]<='Z')
        {
            int level=Level(b,str[i],1);
            printf("结点值为%c的结点在层次%d\n",str[i],level);
        }
    }
    int width=getWidth(b);
    printf("最大宽度:%d\n",width);
    return 0;
}

运行结果如下:

 

在C语言中,我们可以使用递归的方式来二叉树的相关信息: 1. **节点总数**:对于每个节点,它可能是叶节点、左子节点、右子节点或者是根节点。计算节点总数时,需要对每个节点都计数一次。可以定义一个函数,例如`countNodes(node *root)`,该函数接收根节点作为参数,返回整个树的节点数。初始化为0,然后递归历所有子节点。 ```c int countNodes(node* root) { if (root == NULL) return 0; return 1 + countNodes(root->left) + countNodes(root->right); } ``` 2. **叶节点个数**:同样递归处理,如果节点没有孩子,则它是叶节点。在`countNodes`函数中添加一个检查条件即可。 ```c int leafCount(node* root) { if (root == NULL || (root->left == NULL && root->right == NULL)) return 1; return countNodes(root->left) + countNodes(root->right); } ``` 3. **某结点层次**:使用队列(广度优先搜索)可以帮助我们按层二叉树,同时记录当前层的节点数量。当访问到目标节点时,它的层次就是队列长度减一。这里需要一个辅助函数`getNodeLevel(node *root, int targetNode, int level)`。 4. **二叉树宽度**(最大宽度):每次从上一层移向下一层时,记录当前层的最大节点数,因为宽度通常是指每一层的最大节点数。可以使用类似深度优先搜索的方,每遇到新的一层就更新最大宽度。 ```c int maxWidth(node* root) { int maxWidth = 0, levelWidth[100] = {0}; // 假设最多有100层 queue<int> q; if (root != NULL) { q.push(1); // 根节点的层级为1 levelWidth[1] = 1; // 第1层只有一个节点 while (!q.empty()) { int size = q.size(); for (int i = 0; i < size; ++i) { node* node = tree[q.front()]; q.pop(); if (node->left) q.push(node->left->level + 1); if (node->right) q.push(node->right->level + 1); levelWidth[node->level]++; maxWidth = MAX(maxWidth, levelWidth[node->level]); } } } return maxWidth; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值