C++数据结构:二叉树(二)——二叉树的遍历

本文是关于二叉树遍历的讲解,涵盖层序、递归先序、中序、后序遍历以及非递归中序遍历。通过C++代码详细阐述了遍历过程,并提供了运行结果展示。
摘要由CSDN通过智能技术生成

一、序言

在上一篇文章中《二叉树的先序创建》,我们介绍了二叉树的基本结构以及先序建立二叉树,在本篇文章中,我们要对二叉树进行遍历,包括:

  • 层序遍历
  • 递归先序遍历、递归中序遍历、递归后序遍历
  • 非递归中序遍历


二、二叉树的遍历

BiTree.h 头文件新增定义如下,其余部分不变,请参考《二叉树的先序创建》

class BiTree
{
public:
    void LevelOrder();                  //层序遍历
    void PreOrder();                    //先序递归遍历二叉树
    void InOrder();                     //中序递归遍历二叉树
    void PostOrder();                   //后序递归遍历二叉树

    void InOrder2();                    //中序非递归遍历二叉树

};

BiTree.cpp 文件新增定义如下,其余部分不变

#include "BiTree.h"
#include <iostream>
#include <queue>
#include <stack>
using namespace std;
static void LevelTraverse(BiTNode *ptree);  //层序遍历二叉树
static void PreTraverse(BiTNode *ptree);    //递归先序遍历二叉树
static void InTraverse(BiTNode *ptree);     //递归中序遍历二叉树
static void PostTraverse(BiTNode *ptree);   //递归后序遍历二叉树
static void visit(BiTNode *ptree);          //打印数据

//操作:  层序遍历二叉树
//操作前:无参数
//操作后:打印出层序遍历结果
void BiTree::LevelOrder()
{
    cout << "层序遍历二叉树:";
    if (this->root != nullptr)
        LevelTraverse(this->root);      //调用层序遍历二叉树函数
    else
        cout << "二叉树为空" << endl;
    cout << endl;

}
static void LevelTraverse(BiTNode *ptree)
{
    /*
    1.构造辅助队列(我们将直接使用queue库中提供的函数)
    2.先将二叉树的根节点入队,然后出队,访问该节点
    3.如果它有左子树,则将左子树根节点入队
    4.如果它有右子树,则将右子树根节点入队
    5.出队,访问出队节点,如此反复,直到队列为空
    */
    queue<BiTNode *> BiTNodeQueue;                      //队列类型是指向节点的指针类型
    BiTNodeQueue.push(ptree);                           //指向头节点的指针入队
    while (!BiTNodeQueue.empty())                       //队列不为空
    {
        BiTNode *FrontNode = BiTNodeQueue.front();      //队首元素
        visit(FrontNode);                               //访问队首元素
        BiTNodeQueue.pop();                             //队首元素出队
        if (FrontNode->lchild != nullptr)               //如果队首元素这个指针有左孩子则让其入队列
            BiTNodeQueue.push(FrontNode->lchild);
        if (FrontNode->rchild != nullptr)               //如果队首元素这个指针有右孩子则让其入队列
            BiTNodeQueue.push(FrontNode->rchild);
    }//while
}

//操作:  先序递归遍历二叉树
//操作前:无参数
//操作后:打印出先序遍历结果
void BiTree::PreOrder()
{
    cout << "先序遍历二叉树:";
    if (this->root != nullptr)
        PreTraverse(this->root);    //调用先序遍历二叉树函数
    else
        cout << "二叉树为空" << endl;
    cout << endl;

}
static void PreTraverse(BiTNode *ptree)
{
    if (ptree != nullptr)
    {
        visit(ptree);
        PreTraverse(ptree->lchild);
        PreTraverse(ptree->rchild);
    }
}

//操作:  中序递归遍历二叉树
//操作前:无参数
//操作后:打印出中序遍历结果
void BiTree::InOrder()
{
    cout << "中序遍历二叉树:";
    if (this->root != nullptr)
        InTraverse(this->root);     //调用中序遍历二叉树函数
    else
        cout << "二叉树为空" << endl;
    cout << endl;
}
static void InTraverse(BiTNode *ptree)
{
    if (ptree != nullptr)
    {
        InTraverse(ptree->lchild);
        visit(ptree);
        InTraverse(ptree->rchild);
    }
}
//操作:  后序递归遍历二叉树
//操作前:无参数
//操作后:打印出后序遍历结果
void BiTree::PostOrder()
{
    cout << "后序遍历二叉树:";
    if (this->root != nullptr)
        PostTraverse(this->root);       //调用后序遍历二叉树函数
    else
        cout << "二叉树为空" << endl;
    cout << endl;
}
static void PostTraverse(BiTNode *ptree)
{
    if (ptree != nullptr)
    {
        PostTraverse(ptree->lchild);
        PostTraverse(ptree->rchild);
        visit(ptree);
    }
}

//操作:  中序非递归遍历二叉树
//操作前:无参数
//操作后:打印出中序遍历结果
void BiTree::InOrder2()
{
    cout << "中序非递归遍历二叉树:";
    if (this->root != nullptr)
    {
        stack<BiTNode *> BiTNodeStack;
        BiTNode *ptree = this->root;
        while (ptree != nullptr || !BiTNodeStack.empty())   //栈不为空或者ptree不为空时则循环
        {
            if (ptree != nullptr)                           //每当根节点不为空时
            {
                BiTNodeStack.push(ptree);                   //根节点入栈
                ptree = ptree->lchild;                      //ptree指向左子树的根,遍历左子树
            }
            else                                            //每当根节点为空,说明左子树到头了
            {
                BiTNode *TopStack = BiTNodeStack.top();     //当前栈顶元素为最左节点
                visit(TopStack);                            //访问栈顶元素
                BiTNodeStack.pop();                         //栈顶元素出栈,出栈后的新栈顶元素为刚出栈元素的根节点
                ptree = TopStack->rchild;                   //遍历刚出栈元素的右子树
            }
        }//while

    }
    else
        cout << "二叉树为空" << endl;
    cout << endl;
}

static void visit(BiTNode *ptree)
{
    cout << ptree->data << " ";
}

BiTree.cpp 文件定义如下

#include "BiTree.h"
#include <iostream>
using namespace std;
int main()
{
    BiTree tree;
    tree.CreateBiTree();    //先序建立二叉树
    tree.GetBiTRoot();      //获取二叉树的根节点数据
    tree.GetBiTNum();       //获取二叉树的总节点个数
    tree.GetBiTDepth();     //获取二叉树的深度
    tree.LevelOrder();      //二叉树的层序遍历
    tree.PreOrder();        //二叉树的递归先序遍历
    tree.InOrder();         //二叉树的递归中序遍历
    tree.InOrder2();        //二叉树的非递归中序遍历
    tree.PostOrder();       //二叉树的递归后序遍历
    system("pause");
    return EXIT_SUCCESS;
}

三、运行结果

输入二叉树如下图所示

输入二叉树
运行结果

这里写图片描述


如有不对的地方欢迎大家指正交流

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值