先实现一个二叉树节点模板类
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();
}
运行,查看运行结果并分析代码