【BFS】分行层序打印二叉树,分行层序之字形打印二叉树

版权声明:本文为博主原创学习笔记,如需转载请注明来源。 https://blog.csdn.net/SHU15121856/article/details/82584815

面试题32-2:分行层序打印二叉树

从上到下按层打印二叉树,同一层的结点按从左到右的顺序打印,每一层打印到一行。

分行打印,用两个变量一个指示当前行结点数,一个指示下一行结点数。在队列里入栈和出栈时就能维护了。当前行走到0就打完了一行,换行把下一行拿上来。

#include<bits/stdc++.h>
#include "..\Utilities\BinaryTree.h"
using namespace std;

//层序遍历分行打印二叉树
void Print(BinaryTreeNode* pRoot) {
    if(pRoot == nullptr)//非空校验
        return;

    queue<BinaryTreeNode*> nodes;//存二叉树结点地址的队列
    nodes.push(pRoot);//初始放入根节点
    int nextLevel = 0;//队列中,下一层结点的数目
    int toBePrinted = 1;//队列中,当前层还没被打印的节点数
    while(!nodes.empty()) {//只要队列非空
        //每次输出队头
        BinaryTreeNode* pNode = nodes.front();
        printf("%d ", pNode->m_nValue);
        //判空并压入左子结点
        if(pNode->m_pLeft != nullptr) {
            nodes.push(pNode->m_pLeft);
            ++nextLevel;//压入同时将下层结点数+1
        }
        //判空并压入右子结点
        if(pNode->m_pRight != nullptr) {
            nodes.push(pNode->m_pRight);
            ++nextLevel;//压入同时将下层结点数+1
        }
        //弹出刚刚输出过的队头,并将本层节点数-1
        nodes.pop();
        --toBePrinted;
        //[关键]两个变量相互维护
        //如果本层节点数减少到了0
        if(toBePrinted == 0) {
            printf("\n");//那么说明本层已经打印完了,要打印下一层了
            toBePrinted = nextLevel;//将下层结点数复制到本层
            //因为这一次循环一定是出队了"本层"的最后一个结点
            //同时将其携带的"下层"结点入队
            //而这几个结点入队以后"下层"结点就全部入完队了
            //并且没有"下下层"的结点
            nextLevel = 0;//所以此时将下层节点数设置为0
        }
    }
}

//            8
//        6      10
//       5 7    9  11
int main() {
    BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
    BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);
    BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
    BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
    BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);
    BinaryTreeNode* pNode9 = CreateBinaryTreeNode(9);
    BinaryTreeNode* pNode11 = CreateBinaryTreeNode(11);

    ConnectTreeNodes(pNode8, pNode6, pNode10);
    ConnectTreeNodes(pNode6, pNode5, pNode7);
    ConnectTreeNodes(pNode10, pNode9, pNode11);

    Print(pNode8);

    DestroyTree(pNode8);

    return 0;
}

面试题32-3:分行层序之字形打印二叉树

请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。

之字形要用两个栈,一层从左往右进,一层从右往左进。出栈时一个出完再出下一个。
这里写图片描述

#include<bits/stdc++.h>
#include "../Utilities/BinaryTree.h"
using namespace std;


//输入树根,层序之字形打印二叉树
void Print(BinaryTreeNode* pRoot) {
    if(pRoot == nullptr)//非空校验
        return;
    //创建两个栈,分别用来保存之字型的两个顺序
    //在之前写层序遍历中,一个队列里也最多只能出现相邻两层的结点
    //所以两个栈足够用,分别各自交替存放一层的结点(入栈顺序相反),再各自pop至空
    stack<BinaryTreeNode*> levels[2];
    //结合上一道题:按行层序打印二叉树,需要使用两个变量维护
    int current = 0;//当前所在栈号,0栈放偶数层
    int next = 1;//下一层应放在栈号,1栈放奇数层

    levels[current].push(pRoot);//树根压入0号(偶数层)栈
    //只要两个栈都不是空,则逻辑队列非空
    while(!levels[0].empty() || !levels[1].empty()) {
        //取当前层栈顶元素
        BinaryTreeNode* pNode = levels[current].top();
        levels[current].pop();

        printf("%d ", pNode->m_nValue);//层内输出

        //如果当前在0号栈(偶数层栈)
        if(current == 0) {
            //孩子以先左再右的顺序入1号栈(奇数层栈)
            if(pNode->m_pLeft != nullptr)
                levels[next].push(pNode->m_pLeft);
            if(pNode->m_pRight != nullptr)
                levels[next].push(pNode->m_pRight);
        }
        //如果当前在1号栈(奇数层栈)
        else {
            //孩子以先右再左的顺序入0号栈(偶数层栈)
            if(pNode->m_pRight != nullptr)
                levels[next].push(pNode->m_pRight);
            if(pNode->m_pLeft != nullptr)
                levels[next].push(pNode->m_pLeft);
        }
        //如果发现当前栈为空,说明这一层打印完了
        if(levels[current].empty()) {
            printf("\n");//换行
            //换栈,下次循环要打印的是另一个栈了
            //下面的操作就是0变1,1变0
            current = 1 - current;
            next = 1 - next;
        }
    }
}

//            8
//        6      10
//       5 7    9  11
int main() {
    BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
    BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);
    BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
    BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
    BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);
    BinaryTreeNode* pNode9 = CreateBinaryTreeNode(9);
    BinaryTreeNode* pNode11 = CreateBinaryTreeNode(11);

    ConnectTreeNodes(pNode8, pNode6, pNode10);
    ConnectTreeNodes(pNode6, pNode5, pNode7);
    ConnectTreeNodes(pNode10, pNode9, pNode11);

    Print(pNode8);

    DestroyTree(pNode8);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/SHU15121856/article/details/82584815