树(二叉树层次遍历输出及二叉树前序遍历输入)

        前两篇解释了二叉树的有关逻辑概念及前中后序输出递归代码的实现,这篇将讲述二叉树层次遍历输出如何实现以及二叉树前序遍历输入的两种情况。

定义结构体

struct BiNode{
    char data;
    BiNode *lchild,*rchild;
};
typedef BiNode *BiTree;

构造空二叉树 

int InitBiTree(BiTree &T)
{
    T =NULL;
    return 0;
}

按层次遍历输出二叉树

        层次遍历的规则是:从根结点开始,从上到下从左到右逐层遍历。

void LevelTraverse(BiTree T){
    if(T != NULL)//T不是#就执行
    {
        queue<BiTree> q;//新建队列q 队内元素的类型是BiTree
        q.push(T);//T入队
        while(!q.empty())//队列不为空时就执行
        {
            BiNode* node = q.front();//取队列首个元素并赋值给node
            cout << node -> data;//输出node的值
            q.pop();//剔除队列首个元素
            
            if(node -> lchild != NULL)
                q.push(node -> lchild);//如果node的左子不为空将左子入队
            if(node -> rchild != NULL)
                q.push(node -> rchild);//如果node的右子不为空将右子入队
        }
    }
}

        层次遍历代码利用队列先进先出的特性来实现,逻辑单元是先将一个根结点入队,用front函数取最先入队的根结点,再把它输出后剔除掉,后续将根结点的左子和右子分别入队;此时队列最前的是左子,按照处理根结点的方法再处理左子;左子剔除后队列最前的是右子,按照同样的方法处理右子,然后是左子的左子...按照这个思路剔除一个根结点进来左子和右子,直到最后一层,所有叶子结点输出后,树中再无元素,此时,队列中也空了 ,按层次遍历输出结束。由此可见,逻辑单元执行的条件是队列不为空。

        总结代码的结构就是:

        1、判断树不为空后先定义队列并把根入队;

        2、输出并剔除根结点;

        3、将左子和右子入队;

        4、直到队列为空时输出结束;

        注意这里的根、左子、右子都是相对而言的,一些结点它既是它父结点的子也是它子结点的根,所以它是根是子按需要定义。

按前序遍历输入二叉树

        方法一

        输入字符串为二叉树的带虚结点表示的前序遍历序

char *CreateBiTree(BiTree &T,char *str)
{
    //约定#表示空结点
    if(*str == '#')
    {
        T = NULL;
        return str+1;
    }

    //创建结点
    T = new BiNode;
    T->data = *str;

    //继续输入并构造左子树和右子树
    char * strAfterLeft = CreateBiTree(T->lchild, str + 1);
    char * strAfterRight = CreateBiTree(T->rchild, strAfterLeft);

    //返回剩余字符串
    return strAfterRight;
}

        该段代码我的理解方式是用手运行一遍,这里举例输入的字符串为ab##c##,建议大家用手运行一下然后不懂的地方再看我下面的解释,不亲手运行只看别人的理解很难看下去。

        *str指向a,a不是#,创建一个结点T,T的值为a;

        运行strAfterLeft1这一行,str+1所以str指向了b,b不是#,创建新结点,a->lchild的值是b;

        再次运行strAfterLeft2这一行,str +1所以str指向了#,#是#,b->lchild为NULL,返回str + 1,strAfterLeft2指向了#;

        再运行strAfterRight2这一行,strAfterLeft2指向了#,所以b->rchild为NULL,返回str +1给strAfterRight2,strAfterRight2指向了c,再返回strAfterRight2给strAfterLeft1;

        再运行strAfterRight1这一行,c不是#,创建新结点所以a->rchild的值为c,后续右子树c的遍历与b一样;

        方法二

        输入为样例个数及多个二叉树的带虚结点表示的前序遍历序或单个二叉树的带虚结点表示的前序遍历序

void ManuallyCreateTree(BiTree & T)
{
    T = new BiNode;
    char q;
    cin >> q;
    if(q == '#')
        T = NULL;
    else{
        T -> data = q;
        ManuallyCreateTree(T->lchild);
        ManuallyCreateTree(T->rchild);
    }
}

        因为输入为二叉树的带虚结点表示的前序遍历序,所以构造一种完全模拟二叉树前序遍历法则的函数,将字符一个个添加到二叉树中,最终由一个根搭建起整棵树。

//这篇的内容到这里就结束啦 欢迎大家批评指正( ¨̮ )

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值