[C++] 非递归实现前中后序遍历二叉树

网上代码一搜一大片,大同小异咯。
书上的函数实现代码甚至更胜一筹,而且抄一遍就能用,唯一问题是没有写二叉树节点和树的模版类的构造实现,和没有具体实现 visit 函数(也没说明,略坑)。

只需要前中后序遍历的话很多函数都不需要,此外值得吐槽的一点是,明明 BinaryTreeNode 类里面接口写的很明确,私有成员也都保护起来了,最后却把 BinaryTree 添加为了友元类,这波操作着实令人费解。
为了添加这个友元类还需要先进行两个类的声明,之后才能逐个实现,迷了。
但这都不是我按顺序实现了接口函数,最后还是没有调用接口函数的理由。所以根本原因其实就是懒。

前置技能

四种遍历方法分别为:

  • 层次遍历 “ 从上到下,从左到右 ”
  • 前序遍历 “ 根结点 -> 左子树 -> 右子树 ”
  • 中序遍历 “ 左子树 -> 根结点 -> 右子树 ”
  • 后序遍历 “ 左子树 -> 右子树 -> 根结点 ”
[C++] 非递归实现前中后序遍历二叉树_第1张图片
图片来自网络

层次遍历使用了队列进行实现,而前中后序遍历是利用的栈来实现。而前序遍历、中序遍历和后序遍历中,后序遍历的实现无疑是最复杂的。

需求描述

直接上头文件,需要注意的是我没有实现建树、删树和插入的函数,顺手还多抄了一个层次遍历的函数。整体来看是一个很菜的代码,只在主函数里随便构了一个二叉树测试遍历函数。
全部都是模版类的实现写起来很麻烦,实现好了很舒服23333
binarytree.h


template
class BinaryTreeNode;

template
class BinaryTree;

template
class BinaryTreeNode{
private:
    T element;                        //数据域
    BinaryTreeNode * leftChild;    //左孩子
    BinaryTreeNode * rightChild;   //右孩子
public:
    BinaryTreeNode();                 //默认构造
    BinaryTreeNode(T& ele);           //给定数据域值的构造
    BinaryTreeNode(T& ele, BinaryTreeNode * l, BinaryTreeNode * r);
    BinaryTreeNode * getLeftChild();           //返回左孩子
    BinaryTreeNode * getRightChild();          //返回右孩子
    bool setLeftChild(BinaryTreeNode * l);     //设置左孩子
    bool setRightChild(BinaryTreeNode * r);    //设置右孩子
    T getValue() const;                           //返回数据值
    bool isLeaf() const;                          //判断是否为叶子节点
    friend class BinaryTree;
};

template
class BinaryTree{
private:
    BinaryTreeNode * root;  //根节点
public:
    BinaryTree();              //默认构造
    BinaryTree(BinaryTreeNode * r);
    ~BinaryTree();             //析构
    bool isEmpty() const;      //判断是否为空树
    void visit(BinaryTreeNode * pointer);
    BinaryTreeNode * getRoot() const;              //返回根节点
    void preOrder(BinaryTreeNode * root);          //先序遍历
    void inOrder(BinaryTreeNode * root);           //中序遍历
    void postOrder(BinaryTreeNode * root);         //后序遍历
    void levelOrder(BinaryTreeNode * root);        //层次遍历
};

具体实现

binarytree.cpp

#include"binarytree.h"
#include
#include
#include

template
BinaryTreeNode::BinaryTreeNode(){
    element = 0;
    leftChild = nullptr;
    rightChild = nullptr;
}

template
BinaryTreeNode::BinaryTreeNode(T& ele){
    element = ele;
    leftChild = nullptr;
    rightChild = nullptr;
}
template
BinaryTreeNode::BinaryTreeNode(T& ele, BinaryTreeNode * l, 
                                  BinaryTreeNode * r){
    element = ele;
    leftChild = l;
    rightChild = r;
}

template
BinaryTreeNode * BinaryTreeNode::getLeftChild(){
    return leftChild;
}

template
BinaryTreeNode * BinaryTreeNode::getRightChild(){
    return rightChild;
}

template
T BinaryTreeNode::getValue() const{
    return element;
}

template
bool BinaryTreeNode::setLeftChild(BinaryTreeNode * l){
    if(leftChild == nullptr){
        leftChild = l;
        return true;
    }
    else return false;
}

template
bool BinaryTreeNode::setRightChild(BinaryTreeNode * r){
    if(rightChild == nullptr){
        rightChild = r;
        return true;
    }
    else return false;
}

template
bool BinaryTreeNode::isLeaf() const{
    if(leftChild == nullptr && rightChild == nullptr)
        return true;
    else return false;
}

template
BinaryTree::BinaryTree(){
    root = nullptr;
}

template
BinaryTree::BinaryTree(BinaryTreeNode * r){
    root = r;
}

template 
BinaryTree::~BinaryTree(){
    root = nullptr;
}

template
bool BinaryTree::isEmpty() const{
    if (root == nullptr)    return true;
    else return false;
}

template
BinaryTreeNode * BinaryTree::getRoot() const{
    return root;
}

template
void BinaryTree::visit(BinaryTreeNode * pointer){
    std::cout<element<
void BinaryTree::preOrder(BinaryTreeNode * root){
    using std::stack;
    stack * > nodeStack;
    BinaryTreeNode * pointer = root;
    while(!nodeStack.empty()||pointer != nullptr){
        if(pointer != nullptr){
            visit(pointer);
            if(pointer -> rightChild !=  nullptr)
                nodeStack.push(pointer->rightChild);
            pointer = pointer->leftChild;
        }
        else{
            pointer = nodeStack.top();
            nodeStack.pop();
        }
    }
}

template
void BinaryTree::inOrder(BinaryTreeNode * root){
    using std::stack;
    stack * > nodeStack;
    BinaryTreeNode * pointer = root;
    while(!nodeStack.empty()||pointer){
        if(pointer){
            nodeStack.push(pointer);
            pointer = pointer -> leftChild;
        }
        else{
            pointer = nodeStack.top();
            visit(pointer);
            pointer = pointer -> rightChild;
            nodeStack.pop();
        }
    }
}

template
void BinaryTree::postOrder(BinaryTreeNode * root){
    using std::stack;
    stack * > nodeStack;
    BinaryTreeNode * pointer = root;
    BinaryTreeNode * pre = root;
    while(pointer != nullptr){
        while(pointer -> leftChild != nullptr){
            nodeStack.push(pointer);
            pointer = pointer -> leftChild;
        }
        while(pointer != nullptr && (pointer -> rightChild == nullptr ||
                                     pre == pointer->rightChild)){
            visit(pointer);
            pre = pointer;
            pointer = nodeStack.top();
            nodeStack.pop();
        }
        nodeStack.push(pointer);
        pointer = pointer -> rightChild;
    }
}

template
void BinaryTree::levelOrder(BinaryTreeNode * root){
    using std::queue;
    queue *>nodeQueue;
    BinaryTreeNode * pointer = root;
    if(pointer)
        nodeQueue.push(pointer);
    while(!nodeQueue.empty()){
        pointer = nodeQueue.front();
        visit(pointer);
        nodeQueue.pop();
        if(pointer->leftChild)  nodeQueue.push(pointer->leftChild);
        if(pointer->rightChild) nodeQueue.push(pointer->rightChild);
    }
}

main.cpp

#include"binarytree.h"
#include 

using namespace std;

int main(){
    int a1,a2,a3,a4,a5;
    cin>>a1>>a2>>a3>>a4>>a5;
    BinaryTreeNode n1(a1),n2(a2),n3(a3),n4(a4),n5(a5);
    BinaryTree t(&n1);
    n1.setLeftChild(&n2);
    n1.setRightChild(&n3);
    n2.setLeftChild(&n4);
    n2.setRightChild(&n5);          //真·随便接的
    cout<<"层次遍历:"<

你可能感兴趣的:([C++] 非递归实现前中后序遍历二叉树)