二叉树的前序、中序、后序遍历

二叉树的结点定义及类定义:BinaryTree.h

因为用的是模板类,.h和.cpp文件不能分开,类定义和函数实现就全写在.h里了

主要是二叉树的前、中、后序的递归与非递归周游

#ifndef BINARYTREE_H_INCLUDED
#define BINARYTREE_H_INCLUDED
#include <iostream>
#include <queue>
#include <vector>
#include <stack>
using namespace std;

template <class T>
class BinaryTree;

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

template <class T>
class BinaryTree{
private:
    BinaryTreeNode<T> *root;                                                 //二叉树根节点
public:
    BinaryTree(){                                                            //默认构造函数
        root = NULL;
    }
    ~BinaryTree(){                                                           //析构函数
        destory(root);
    }
    BinaryTreeNode<T>* creatTree(vector<T> a, int size, int &i, T& invalid){ //创建二叉树
        BinaryTreeNode<T>* _root = NULL;
        if(i < size && a[i] != invalid){
            _root = new BinaryTreeNode<T>();
            _root->setValue(a[i]);
            if(i == 0)
                root = _root;
            _root->setLeftChild(creatTree(a, size, ++i, invalid));
            _root->setRightChild(creatTree(a, size, ++i, invalid));
        }
        return _root;
    }
    void destory(BinaryTreeNode<T>* node){                                   //销毁二叉树
        BinaryTreeNode<T>* temp = node;
        if(temp == NULL)
            return;
        destory(temp->leftChild);
        destory(temp->rightChild);
        delete temp;
        temp = NULL;
    }
    bool isEmpty() const{                                                    //判断二叉树是否为空树
        return (root == NULL);
    }
    BinaryTreeNode<T>* getRoot() const{                                      //返回二叉树的根结点
        return root;
    }
    void setRoot(BinaryTreeNode<T> *node){
        root = node;
    }
    BinaryTreeNode<T>* getParent(BinaryTreeNode<T>* current) const{          //返回current结点的父结点
    }
    BinaryTreeNode<T>* getLeftSibling(BinaryTreeNode<T>* current) const{     //返回current结点的左兄弟
        return current->leftChild;
    }
    BinaryTreeNode<T>* getRightSibling(BinaryTreeNode<T>* current) const{    //返回current结点的右兄弟
        return current->rightChild;
    }
    void breadthFirstOrder(){                                                //广度优先遍历以riit为根结点的子树
        queue<BinaryTreeNode<T> *> nodeQueue;
        BinaryTreeNode<T> *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);
        }
        cout<<endl;
    }
    void PreOrder (BinaryTreeNode<T>* node){                                 //前序递归遍历二叉树或其子树
        BinaryTreeNode<T>* pointer = node;
         if (pointer != NULL) {
            visit(pointer);		                                             // 访问当前结点
            PreOrder(pointer->leftChild);	                                 // 前序遍历左子树
            PreOrder(pointer->rightChild);	                                 // 前序遍历右子树
          }
    }
    void MidOrder (BinaryTreeNode<T>* node){                                 //中序递归遍历二叉树或其子树
        BinaryTreeNode<T>* pointer = node;
         if (pointer != NULL) {
            MidOrder(pointer->leftChild);
            visit(pointer);
            MidOrder(pointer->rightChild);
          }
    }
    void AftOrder (BinaryTreeNode<T>* node){                                 //后序递归遍历二叉树或其子树
        BinaryTreeNode<T>* pointer = node;
         if (pointer != NULL) {
            AftOrder(pointer->leftChild);
            AftOrder(pointer->rightChild);
            visit(pointer);
          }
    }
    void visit(BinaryTreeNode<T>* current){                                  //访问当前结点
        cout<<current->element<<'\t';
    }
    void preTraversal(BinaryTreeNode<T> *root){                              //深度前序非递归周游
        stack<BinaryTreeNode<T>*> s;
        BinaryTreeNode<T>* pointer = root;
        while(!s.empty() || pointer){                                        //栈空且指针指向NULL时停止循环
            if(pointer){
                visit(pointer);
                if(pointer->rightChild != NULL)                              //非空右孩子入栈
                    s.push(pointer->rightChild);
                pointer = pointer->leftChild;
            }else{
                pointer = s.top();                                           //获得栈顶元素
                s.pop();                                                     //弹栈
            }
        }
    }
    void midTraversal(BinaryTreeNode<T> *root){                              //深度中序非递归周游
        stack<BinaryTreeNode<T>*> s;
        BinaryTreeNode<T> *pointer = root;
        while(!s.empty() || pointer){
            if(pointer){
                s.push(pointer);                                             //当前指针入栈
                pointer = pointer->leftChild;                                //左路下降
            }else{                                                           //左子树访问完毕,转向访问右子树
                pointer = s.top();                                           //获得栈顶元素
                s.pop();                                                     //弹栈
                visit(pointer);                                              //访问当前结点
                pointer = pointer->rightChild;                               //指针指向右孩子
            }
        }
    }
    void aftTraversal(BinaryTreeNode<T> *root){                              //深度后序非递归周游
        stack<BinaryTreeNode<T>*> s;
        BinaryTreeNode<T> *p = root,                                         //当前指针
                          *q = root;                                         //上一个访问的指针
        while(p != NULL){
            for(; p->leftChild != NULL; p = p->leftChild)                    //从左下第一个结点开始循环
                s.push(p);
            while(p != NULL && (p->rightChild == NULL || p->rightChild == q)){     //当前结点不为空并且其右孩子为空或访问过则访问当前结点
                visit(p);
                q = p;
                if(s.empty())                                                //栈空则返回
                    return;
                p = s.top();                                                 //弹栈
                s.pop();
            }
            s.push(p);                                                       //当前结点不为空且右孩子没被访问过则当前结点入栈
            p = p->rightChild;
        }
    }
};

#endif // BINARYTREE_H_INCLUDED

根据前序、中序生成二叉树和根据中序、后序生成二叉树:relatedFun.h

#ifndef RELATEDFUN_H_INCLUDED
#define RELATEDFUN_H_INCLUDED
#include<string>
#include "BinaryTree.h"

extern void createTree(string s1, string s2, string type);

#endif // RELATEDFUN_H_INCLUDED

relatedFun.cpp

#include "relatedFun.h"

void preMidCreate(string pre, string mid, BinaryTreeNode<char> *node){  //已知前序中序生成树
    int ssize = pre.size();
    node->setValue(pre[0]);                                             //设定当前结点值为前序字符串第一个字符
    if(ssize == 1)                                                      //字符串长度为1时停止递归
        return;
    else{
        for(int i = 0; i < ssize; i ++){
            if(mid[i] == pre[0]){                                       //中序字符等于前序第一个字符时
                if(i != 0){                                             //如果不在中序字符串首,则有左孩子
                    BinaryTreeNode<char> *left;
                    left = new BinaryTreeNode<char>();                  //创建新结点
                    node->setLeftChild(left);
                    string p (pre.substr(1, i));                        //以当前字符为界分割字符串
                    string m (mid.substr(0, i));
                    preMidCreate(p, m, left);                           //递归调用
                }
                if(i != ssize - 1){                                     //如果不在中序字符串尾,则有右孩子
                    BinaryTreeNode<char> *right;
                    right = new BinaryTreeNode<char>();
                    node->setRightChild(right);
                    string p (pre.substr(i + 1));
                    string m (mid.substr(i + 1));
                    preMidCreate(p, m, right);
                }
            }
        }
    }
}

void midAftCreate(string mid, string aft, BinaryTreeNode<char> *node){  //已知中序后序生成树
    int ssize = mid.size();
    node->setValue(aft[ssize - 1]);                                     //当前字符为后序字符串最后一个字符
    if(ssize == 1)
        return;
    else{
        for(int i = 0; i < ssize; i ++){
            if(mid[i] == aft[ssize - 1]){
                if(i != 0){
                    BinaryTreeNode<char> *left;
                    left = new BinaryTreeNode<char>();
                    node->setLeftChild(left);
                    string a (aft.substr(0, i));
                    string m (mid.substr(0, i));
                    midAftCreate(m, a, left);
                }
                if(i != ssize - 1){
                    BinaryTreeNode<char> *right;
                    right = new BinaryTreeNode<char>();
                    node->setRightChild(right);
                    string a (aft.substr(i, ssize-1));
                    string m (mid.substr(i + 1));
                    midAftCreate(m, a, right);
                }
            }
        }
    }
}

void createTree(string s1, string s2, string type){
    BinaryTree<char> tree;
    BinaryTreeNode<char> *node = new BinaryTreeNode<char>();
    tree.setRoot(node);
    if(type == "premid")
        preMidCreate(s1, s2, node);
    else if(type == "midaft")
        midAftCreate(s1, s2, node);
    tree.preTraversal(tree.getRoot());                   //前序周游二叉树
    cout<<endl;
    tree.midTraversal(tree.getRoot());                   //中序周游二叉树
    cout<<endl;
    tree.aftTraversal(tree.getRoot());                   //后序周游二叉树
    cout<<endl;
}

主函数测试:main.cpp

#include "relatedFun.h"
#include "BinaryTree.h"
#include"stdio.h"

int main()
{
    string pre;
    string mid;
    string aft;
    cout<<"请输入先序序列:"<<endl;
    cin>>pre;
    cout<<"请输入中序序列:"<<endl;
    cin>>mid;
    cout<<"请输入后序序列:"<<endl;
    cin>>aft;
    createTree(pre, mid, "premid");
    createTree(mid, aft, "midaft");
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值