二叉树的建立、遍历以及求树的最大宽度

树是数据结构中很重要的一部分,以下是建立二叉树,遍历二叉树以及在遍历过程中求每层节点数的样例。
建立二叉树有很多种方法,这里采用类的方式来建立。
类的私有数据成员包括该节点的值,它的左儿子以及右儿子。建立二叉树时用new来新建节点并采用指针指向它的左儿子以及右儿子,如果没有左儿子或者右儿子,则为空。
遍历时,从第一个节点出发,一直按照指针指向来寻找,这里采用递归的思想来完成。
如何在递归时计算出每层的节点数是这里要说的重点。这里采用的遍历是先序遍历,这样的话遍历时会一直访问左儿子,一直访问到叶子节点时回溯,回溯到有右儿子的节点开始再进行上述操作,直到整棵树完成遍历。那么我们就可以建立一个一维数组来储存每层的节点数a[i],i为第几层。比如第一层a[1]=1。那么在遍历时就要想办法让i与a[i]对应起来。在判断某节点的左儿子不为空时,其儿子一定在下一层,即下一层一定存在元素,此时将i++,a[i]++。如果遍历时回溯了,说明已经下探到了最后一层,要开始往上找了,此时将i–,a[i]不需要管。这样一来,递归完成时,就将每一层的节点数储存在了a[i]的数组中。代码如下:

#include<bits/stdc++.h>
using namespace std;
int a[100];
int i;
int Count=0;
class Tree
{
    int member;
    Tree *left;
    Tree *right;
public:
    Tree(){}
    void input();
    void display();
};
void Tree::input()
{
    int t;
    cin>>member;
    cout<<"是否有左儿子  有按1  没有按2"<<endl;
    cin>>t;
    if(t==1)
    {
        left=new Tree;
        left->input();
    }
    else left=NULL;
    cout<<"是否有右儿子  有按1  没有按2"<<endl;
    cin>>t;
    if(t==1)
    {
        right=new Tree;
        right->input();
    }
    else right=NULL;
}
void Tree::display()
{
    Tree *n;
    //cout<<member;
    if(left!=NULL)
    {
        i++;
        a[i]++;
        n=left;
        n->display();
    }
    if(right!=NULL)
    {
        i++;
        a[i]++;
        n=right;
        n->display();
    }
    Count=max(Count,i);
    i--;
}
int main()
{
    memset(a,0,sizeof(a));
    i=1;
    a[1]=1;
    Tree A;
    A.input();
    A.display();
    cout<<endl;
    int Max=0;
    cout<<Count<<endl;
    for(int i=1;i<=Count;i++)
    {
        cout<<"第"<<i<<"层的节点数为:"<<a[i]<<endl;;
        Max=max(Max,a[i]);
    }
    cout<<"数的宽度为:"<<Max<<endl;
    return 0;
}

这里树的宽度即节点数最多的那一层节点数,实现时只需要寻找a[i]中最大的数即可。
当然,求每层的节点数不止这一种方法,也可以运用队列来实现,这里不再赘述。
从代码量上来说,这个方法比用队列方法代码量略少,但不太容易理解,算是各有利弊吧。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值