C++实现二叉树和二叉树的遍历

一、前言

1.通过组合模式来实现二叉树 一共有两个类
(组合模式是面向对象23种设计模式的一种)
BinaryTree类(二叉树类) 代表 整体
BinaryTreeNode(节点) 代表 个体
2.BinaryTreeNode:
定义私有成员变量 左右孩子 以及data(数据域)
提供三个私有变量的get 和set 接口函数
3.BinaryTree :
有BinaryTreeNode 的成员变量用来存储根节点。
有7中不同方法遍历二叉树的成员函数
(前\中\后序遍历 非递归前\中\后序遍历 层序遍历)
4.说明
组合模式就是把个体组合成一个整体
如果是对整个树的操作就调用树的函数
如果是针对某个结点操作就调用结点函数

二、BinaryTreeNode类

1.需求分析
①因为我们不知道我们要对什么数据类型或者什么类建立二叉树结构 ,所以data(数据域)需要设置不定类型,因此我们选择使用模板类来实现。
②私有成员变量 data rightNode(右孩子) leftNode(左孩子) 分别对三个变量定义get 和 set 两个接口函数(封装)
2.代码:

/*
*BinaryTreeNode.h
*@author zht
*/
#ifndef BINARYTREENODE_H
#define BINARYTREENODE_H
#include <iostream>
using namespace std;
template<typename ElemType>
class BinaryTreeNode
{
public:
    //构造函数
    BinaryTreeNode(ElemType value);
    //赋值
    void setValue(ElemType value);
    //获取值
    ElemType getValue();
    //设置左结点
    template <typename T>
    void setLeftNode(BinaryTreeNode<T> * leftNode);
    //获取左结点
    BinaryTreeNode<ElemType> * getLeftNode();
    //设置右结点
    template <typename T>
    void setRightNode(BinaryTreeNode<T> * rightNode);
    //获取右结点
    BinaryTreeNode<ElemType> * getRightNode();
private:
    //数据域
    ElemType value;
    //左孩子
    BinaryTreeNode<ElemType> * leftNode = NULL;
    //右孩子
    BinaryTreeNode<ElemType> * rightNode = NULL;
};
/** \brief
 * 带参构造函数,初始化数据域
 * \param value 结点数据
 * \return 构造函数无返回值
 *
 */
template <typename ElemType>
BinaryTreeNode<ElemType>::BinaryTreeNode(ElemType value)
{
    this->value = value;
}
/** \brief
 *  用来对数据域重新赋值
 * \param value 结点数据
 * \return 无返回值
 *
 */
template <typename ElemType>
void BinaryTreeNode<ElemType>::setValue(ElemType value)
{
    this->value = value;
}
/** \brief
 *  用来获取数据域的值
 * \return 返回数据域的值
 *
 */
template <typename ElemType>
ElemType BinaryTreeNode<ElemType>::getValue()
{
    return this->value;
}
/** \brief
 *  用来对左孩子赋值
 * \param leftNode 一个结点
 * \return 无返回值
 *
 */
template<typename ElemType>
template <typename T>
void BinaryTreeNode<ElemType>::setLeftNode(BinaryTreeNode<T> * leftNode)
{
    this->leftNode = leftNode;
}
/** \brief
 *  用来获取当前结点的左结点
 * \return 返回当前结点的左结点
 *
 */
template<typename ElemType>
BinaryTreeNode<ElemType> * BinaryTreeNode<ElemType>::getLeftNode()
{
    return this->leftNode;
}
/** \brief
 *  用来对右孩子赋值
 * \param rightNode 一个结点
 * \return 无返回值
 *
 */
template<typename ElemType>
template <typename T>
void BinaryTreeNode<ElemType>::setRightNode(BinaryTreeNode<T> * rightNode)
{
    this->rightNode = rightNode;
}
/** \brief
 *  用来获取当前结点的右结点
 * \return 返回当前结点的右结点
 *
 */
template<typename ElemType>
BinaryTreeNode<ElemType> * BinaryTreeNode<ElemType>::getRightNode()
{
    return this->rightNode;
}
#endif // BINARYTREENODE_H

三、BinaryTree类

1.需求分析
①结点类是模板类所以树类也是模板类
②私有成员 root(用来存放根结点),通过构造函数初始化
③主要函数:七种遍历的函数以及判断树是否为空,求树的深度的的函数
④遍历所用到的队列代码放最后面

#ifndef BINARYTREE_H_INCLUDED
#define BINARYTREE_H_INCLUDED
/*
*@author zht
*/
#include "BinaryTreeNode.h"
#include <stack>
#include"../../sequentialQueue/SequenceQueue.h"
using namespace std;
template<typename ElemType>
class BinaryTree
{
public:
    template<typename T>
    BinaryTree(BinaryTreeNode<T> * node);
    BinaryTree();
    //树是否为空
    bool isEmpty();
    //树的深度
    int binaryTreeDepth();
    //先序遍历
    bool preOrderTraverse();
    //中序遍历
    bool inOrderTraverse();
    //后续遍历
    bool postOrderTraverse();
    //层序遍历
    bool levelOrderTraverse();
    //非递归先序遍历
    bool nonRecpreOrderTraverse();
    //非递归中序遍历
    bool nonRecInOrderTraverse();
    //非递归后序遍历
    bool nonRecpostOrderTraverse();
private:
    //根节点
    BinaryTreeNode<ElemType> * root;
    //深度
    template<typename T>
    int binaryTreeDepthTemp(BinaryTreeNode<T> * node);
    //先序遍历
    template<typename T>
    bool preOrderTraverseTemp(BinaryTreeNode<T> * node);
    //中序遍历
    template<typename T>
    bool inOrderTraverseTemp(BinaryTreeNode<T> * node);
    //后序遍历
    template<typename T>
    bool postOrderTraverseTemp(BinaryTreeNode<T> * node);

};
//带参构造函数
template<typename ElemType>
template<typename T>
BinaryTree<ElemType>::BinaryTree(BinaryTreeNode<T> * node)
{
    this->root = node;
}
//无参构造函数
template<typename ElemType>
BinaryTree<ElemType>::BinaryTree()
{
    this->root = NULL;
}
/** \brief 
 * 判断二叉树是否为空
 * \return 为空返回true 不为空返回false
 *
 */     
template<typename ElemType>
bool BinaryTree<ElemType>:: isEmpty()
{
    if(this->root ==NULL)
    {
        return true;
    }
    return false;
}
/** \brief 计算二叉树的深度
 * 通过递归来计算二叉树的深度
 * \return 返回二叉树的深度
 *
 */     

template<typename ElemType>
template<typename T>
int BinaryTree<ElemType>::binaryTreeDepthTemp(BinaryTreeNode<T> * node)
{
    int  leftHeight;
    int  rightHeight;
    int  maxHeight;
    if (node != NULL)
    {
        leftHeight = binaryTreeDepthTemp(node->getLeftNode());
        rightHeight = binaryTreeDepthTemp(node->getRightNode());
        maxHeight = leftHeight>rightHeight?leftHeight:rightHeight;
        return maxHeight+1;
    }
    else
    {
        return 0;
    }
}
template<typename ElemType>
int BinaryTree<ElemType>::binaryTreeDepth()
{
    return binaryTreeDepthTemp(this->root);
}
//*****先序遍历*****//
template<typename ElemType>
template<typename T>
bool BinaryTree<ElemType>::preOrderTraverseTemp(BinaryTreeNode<T> * node)
{
    if( node != NULL)
    {
        cout << node->getValue() << '\t';
        preOrderTraverseTemp(node->getLeftNode());
        preOrderTraverseTemp(node->getRightNode());
    }
    return true;
}
template<typename ElemType>
bool BinaryTree<ElemType>::preOrderTraverse()
{
    preOrderTraverseTemp(this->root);
    return true;
}
//*****END*****//

//*****中序遍历*****//
template<typename ElemType>
template<typename T>
bool BinaryTree<ElemType>::inOrderTraverseTemp(BinaryTreeNode<T> * node)
{
    if( node != NULL)
    {
        inOrderTraverseTemp(node->getLeftNode());
        cout << node->getValue() << '\t';
        inOrderTraverseTemp(node->getRightNode());
    }
    return true;
}
template<typename ElemType>
bool BinaryTree<ElemType>::inOrderTraverse()
{
    inOrderTraverseTemp(this->root);
    return true;
}
//*****END*****//

//*****后序遍历*****//
template<typename ElemType>
template<typename T>
bool BinaryTree<ElemType>::postOrderTraverseTemp(BinaryTreeNode<T> * node)
{
    if( node != NULL)
    {
        postOrderTraverseTemp(node->getLeftNode());
        postOrderTraverseTemp(node->getRightNode());
        cout << node->getValue() << '\t';
    }
    return true;
}
template<typename ElemType>
bool BinaryTree<ElemType>::postOrderTraverse()
{
    postOrderTraverseTemp(this->root);
    return true;
}
//*****END*****//

//*****非递归先序遍历*****//
template<typename ElemType>
bool BinaryTree<ElemType>::nonRecpreOrderTraverse()
{
    BinaryTreeNode<ElemType> * temp = this->root;
    stack<BinaryTreeNode<ElemType>*> s;
    s.push(temp);
    while(!s.empty()||temp!=NULL)
    {
        temp = s.top();
        s.pop();
        while(temp!=NULL)
        {
            cout << temp->getValue() << '\t';
            if(temp->getRightNode()!=NULL)
            {
                s.push(temp->getRightNode());
            }
            temp = temp->getLeftNode();
        }

    }
    return true;
}
//*****END*****//

//*****非递归中序遍历*****//
template<typename ElemType>
bool BinaryTree<ElemType>::nonRecInOrderTraverse()
{
    BinaryTreeNode<ElemType> * temp = this->root;
    stack<BinaryTreeNode<ElemType>*> s;
    while(!s.empty()||temp !=NULL)
    {
        if(temp != NULL)
        {
            s.push(temp);
            temp = temp->getLeftNode();
        }
        else
        {
            temp = s.top();
            s.pop();
            cout << temp->getValue() << '\t';
            temp = temp->getRightNode();
        }
    }
    return true;
}
//*****END*****//

//*****非递归后序遍历*****//
template<typename ElemType>
class SNode
{
public:
    stack<int> tag;
    stack<BinaryTreeNode<ElemType> *>s;

};
template<typename ElemType>
bool BinaryTree<ElemType>::nonRecpostOrderTraverse()
{
    SNode<ElemType> sNode;
    BinaryTreeNode<ElemType> * temp = this->root;
    int tag;
    while(temp !=NULL || !sNode.s.empty())
    {

        while(temp!=NULL)
        {
            sNode.s.push(temp);
            tag = 0;
            sNode.tag.push(tag);
            temp = temp->getLeftNode();
        }
        temp = sNode.s.top();
        sNode.s.pop();
        tag = sNode.tag.top();
        sNode.tag.pop();
        if(tag == 0)
        {
            sNode.s.push(temp);
            tag = 1;
            sNode.tag.push(tag);
            temp =temp->getRightNode();
        }
        else
        {
            cout << temp->getValue() <<'\t';
            temp = NULL;
        }
    }

    return true;
}
//*****END*****//

//*****层序遍历*****//
template<typename ElemType>
bool BinaryTree <ElemType>::levelOrderTraverse()
{
    SequenceQueue<BinaryTreeNode<ElemType>*> sequenceQueue;
    BinaryTreeNode<ElemType>  *p;
    //根节点
    sequenceQueue.enQueue(this->root);
    while(sequenceQueue.front!=sequenceQueue.rear)
    {
        p = sequenceQueue.deQueue();
        cout << p->getValue() << '\t';
        if(p->getLeftNode() !=NULL)
        {
            sequenceQueue.enQueue(p->getLeftNode());
        }
        if(p->getRightNode() !=NULL)
        {
            sequenceQueue.enQueue(p->getRightNode());
        }
    }
    return true;
}
//*****END*****//
#endif // BINARYTREE_H_INCLUDED

四、运行结果

1.主函数代码

#include "BinaryTreeNode.h"
#include "BinaryTree.h"

int main()
{
    BinaryTreeNode<int> * _100 = new BinaryTreeNode<int>(100);
    BinaryTreeNode<int> * _200 = new BinaryTreeNode<int>(200);
    BinaryTreeNode<int> * _300 = new BinaryTreeNode<int>(300);
    BinaryTreeNode<int> * _400 = new BinaryTreeNode<int>(400);
    BinaryTreeNode<int> * _500 = new BinaryTreeNode<int>(500);
    BinaryTreeNode<int> * _600 = new BinaryTreeNode<int>(600);
    BinaryTree<int> * binaryTree = new BinaryTree<int>(_100);
    _100->setLeftNode(_200);
    _100->setRightNode(_300);
    _300->setLeftNode(_400);
    _300->setRightNode(_500);
    _200->setRightNode(_600);
    //非递归前序遍历
    cout << "非递归前序遍历:";
    binaryTree->nonRecpreOrderTraverse();
    cout << endl;
    //非递归中序遍历
    cout << "非递归中序遍历:";
    binaryTree->nonRecInOrderTraverse();
    cout << endl;
    //非递归后序遍历
    cout << "非递归后序遍历:";
    binaryTree->nonRecpostOrderTraverse();
    cout << endl;
    //层序遍历
    cout << "层序遍历:";
    binaryTree->levelOrderTraverse();
    cout << endl;
    //前序遍历
    cout << "前序遍历:";
    binaryTree->preOrderTraverse();
    cout << endl;
    //前序遍历
    cout << "中序遍历:";
    binaryTree->inOrderTraverse();
    cout << endl;
    //后序遍历
    cout << "后序遍历:";
    binaryTree->postOrderTraverse();
    cout << endl;
    return 0;
}

2.运行结果
非常完美

五、顺序队列代码

#ifndef SEQUENCEQUEUE_H_INCLUDED
#define SEQUENCEQUEUE_H_INCLUDED

/*
*@author zht
*顺序队列
*/
#include <iostream>
using namespace std;
template<typename ElemType>
class SequenceQueue
{
private:
    //队列
    ElemType   arrays[1024];
public:
    //队头指针
    ElemType *front =arrays ;
    //队尾指针
    ElemType *rear =arrays;
    SequenceQueue();
    //入队
    template <typename T>
    bool enQueue(T data);
    //出队
    ElemType deQueue();
};
template<typename ElemType>
SequenceQueue<ElemType>::SequenceQueue()
{
}
template<typename ElemType>
template <typename T>
bool SequenceQueue<ElemType>::enQueue(T data)
{
    //cout << data;
    *rear = data;
    rear++;
    return true;
}
template<typename ElemType>
ElemType SequenceQueue<ElemType>::deQueue()
{
    ElemType data ;
    if(rear == front)
    {
        data = 0;
        return  data;
    }
    data = *front;
    front++;
    return data;
}
#endif // SEQUENCEQUEUE_H_INCLUDED

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值