C++实现的二叉树模板及其应用实例

先实现一个二叉树节点模板类

bintreenode.h文件

#ifndef BINTREENODE_H
#define BINTREENODE_H

template<class T>
class BinTreeNode
{

public:
    T data;
    int depth; //结点的深度
    BinTreeNode<T> *parent;
    BinTreeNode<T> *leftChild;
    BinTreeNode<T> *rightChild; //变量定义 与构造顺序应一致
    BinTreeNode()
    {
        depth=0;
        parent=NULL;
        leftChild=rightChild=NULL;
    }
    BinTreeNode(const T &val,int Depth=0,
                BinTreeNode<T> *Parent=NULL,
                BinTreeNode<T> *lChild=NULL,
                BinTreeNode<T> *rChild=NULL)
        :data(val),depth(Depth),parent(Parent),leftChild(lChild),rightChild(rChild){}
    bool isDescendent(BinTreeNode<T>* binNode);//是否是自己的后代
};

#endif // BINTREENODE_H

template<class T>
bool BinTreeNode<T>::isDescendent(BinTreeNode<T> *binNode)
{
    BinTreeNode<T> *parentBinNode=binNode->parent;
    while (parentBinNode)
    {
        if(parentBinNode==this)
        {
            return true;
        }
        parentBinNode=parentBinNode->parent;
    }
    return false;
}

实现二叉树模板类

binarytree.h文件

#ifndef BINARYTREE_H
#define BINARYTREE_H
#include"bintreenode.h"
#include<QDebug>
#include<QString>
#include<QQueue>
#include<functional>

template<class T>
class BinaryTree
{
protected:
    BinTreeNode<T> *root;  //根节点
public:
    int height;  //树的高度
public:
    BinaryTree();
    BinaryTree(const T &e,int depth=0); //缺省深度为0
    virtual ~BinaryTree();
    BinTreeNode<T>* getRoot();
    void destroyNode(BinTreeNode<T> *node);

    void preorderTravel(BinTreeNode<T> *node,void (*visit)(T &)); //前序遍历

    void levelTravel(void (*visit)(BinTreeNode<T> *node)); //层次遍历
    BinTreeNode<T>* insertLeftChild(BinTreeNode<T> *cur,const T &e);
    BinTreeNode<T>* insertRightChild(BinTreeNode<T> *cur,const T &e);
    bool isCompleteTree();

    //可用指向类函数成员的指针作为参数
    void levelTreeTravel(std::function<void(BinTreeNode<T> *node)> visit); //层次遍历
    void postOrderTravel(BinTreeNode<T> *node,std::function<void(BinTreeNode<T> *)> visit); //后序遍历
};

template<class T>
BinaryTree<T>::BinaryTree()
{
    root=NULL;
    height=-1;
}

template<class T>
BinaryTree<T>::BinaryTree(const T &e,int depth)
{
    root=new BinTreeNode<T>(e,depth);
    height=0;
}

template<class T>
BinTreeNode<T> *BinaryTree<T>::getRoot()
{
    return root;
}

template<class T>
BinTreeNode<T>* BinaryTree<T>::insertLeftChild(BinTreeNode<T> *cur, const T &e)
{
    int depth=cur->depth+1;//子结点总比父结点深度多1
    if(depth>this->height)
    {
        this->height=depth;
    }
    //语句的精炼与可读性
//    BinTreeNode<T> *lChild=new BinTreeNode<T>(e,depth,cur);
//    cur->leftChild=lChild;
//    return cur->leftChild;

    return cur->leftChild=new BinTreeNode<T>(e,depth,cur);
}

template<class T>
BinTreeNode<T> *BinaryTree<T>::insertRightChild(BinTreeNode<T> *cur, const T &e)
{
    int depth=cur->depth+1;//子结点比父结点深度多1
    if(depth>this->height)
    {
        this->height=depth;
    }
    return cur->rightChild=new BinTreeNode<T>(e,depth,cur);
}

//判断是否为完全树
/*中层遍历:从上到下,从左到右
 *
*/
template<class T>
bool BinaryTree<T>::isCompleteTree()
{
    QQueue<BinTreeNode<T>*> queue; //辅助队列
    if(root)
    {
        queue.enqueue(root);
    }
    else
    {
        return true;
    }
    BinTreeNode<T>* cur=NULL;
    while (queue.isEmpty()==false)
    {
       cur=queue.dequeue();
       //当前结点具有两个孩子结点
       if(cur->leftChild && cur->rightChild)
       {
           queue.enqueue(cur->leftChild);
           queue.enqueue(cur->rightChild);
           continue;
       }
       //当前结点没有孩子结点
       else if(cur->leftChild==NULL && cur->rightChild==NULL)
       {
           continue;
       }
       else   //有一个孩子结点
       {
           return false;
       }
    }
    return true;
}


template<class T>
BinaryTree<T>::~BinaryTree()
{
    destroyNode(root);
}

//postorder
template<class T>
void BinaryTree<T>::destroyNode(BinTreeNode<T> *node)
{
    static int i=0;
    if(node)
    {
        destroyNode(node->leftChild);
        destroyNode(node->rightChild);

        delete node;
        qDebug()<<QString::number(i++);
        node=NULL;
    }
}

//先序遍历
template<class T>
void BinaryTree<T>::preorderTravel(BinTreeNode<T> *node, void (*visit)(T &))
{
    if(node)
    {
        (*visit)(node->data);
        preorderTravel(node->leftChild,visit);
        preorderTravel(node->rightChild,visit);
    }
}

template<class T>
void BinaryTree<T>::levelTravel(void (*visit)(BinTreeNode<T> *))
{
    QQueue<BinTreeNode<T>*> queue; //辅助队列
    if(root)
    {
        queue.enqueue(root);
    }
    else
    {
        return;
    }
    BinTreeNode<T>* cur=NULL;
    while (queue.isEmpty()==false)
    {
       cur=queue.dequeue();
       visit(cur);
       if(cur->leftChild)
       {
           queue.enqueue(cur->leftChild);
       }

       if(cur->rightChild)
       {
           queue.enqueue(cur->rightChild);
       }

    }
}


template<class T>
void BinaryTree<T>::levelTreeTravel(std::function<void(BinTreeNode<T> *node)> visit)
{
    QQueue<BinTreeNode<T>*> queue; //辅助队列
    if(root)
    {
        queue.enqueue(root);
    }
    else
    {
        return;
    }
    BinTreeNode<T>* cur=NULL;
    while (queue.isEmpty()==false)
    {
       cur=queue.dequeue();
       visit(cur);

       if(cur->leftChild)
       {
           queue.enqueue(cur->leftChild);
       }

       if(cur->rightChild)
       {
           queue.enqueue(cur->rightChild);
       }

    }
}

template<class T>
void BinaryTree<T>::postOrderTravel(BinTreeNode<T> *node, std::function<void (BinTreeNode<T> *)> visit)
{
    if(node)
    {
        postOrderTravel(node->leftChild,visit);
        postOrderTravel(node->rightChild,visit);
        visit(node);
    }
}

#endif // BINARYTREE_H

二叉树模板的应用实例

使用Qt创建一个控制台工程;
将上述两个文件添加工程中;
编辑main.cpp

#include <QCoreApplication>
#include"binaryTree_node_template/binarytree.h"
#include<QDebug>
struct myStruct{
    int num;
    QString name;
    myStruct(int _num,QString _name)
    {
        num=_num;
        name=_name;
    }

};

void print(BinTreeNode<myStruct*> *data)
{
    qDebug()<<data->data->num<<data->data->name;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    //实例化二叉树根节点
    struct myStruct *rootData=new myStruct(1,"china");
    BinaryTree<myStruct*> binaryTree(rootData);

    BinTreeNode<myStruct*>* rootNode=binaryTree.getRoot();

    //为根节点添加左节点leftChild
    BinTreeNode<myStruct*>* leftChild=binaryTree.insertLeftChild(rootNode,new myStruct(2,"nenan"));
    //为根节点添加右节点rightChild
    BinTreeNode<myStruct*>* rightChild=binaryTree.insertRightChild(rootNode,new myStruct(3,"hebei"));
    //为leftChild节点添加左节点
    binaryTree.insertLeftChild(leftChild,new myStruct(4,"luoyang"));
    //为rightChild节点添加右节点
    binaryTree.insertLeftChild(rightChild,new myStruct(5,"shijiazhang"));

    binaryTree.levelTravel(print);

    return a.exec();
}

运行,查看运行结果并分析代码

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蔡云辉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值