一、前言
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