循环遍历二叉树
#include<iostream>
#include<memory.h>
using namespace std;
template<class type> //栈模板
class CStact {
private:
type *m_pTop; //栈顶
type *m_pBottom; //栈底
int m_nStackSize; //栈大小
public:
CStact() {
m_pTop = NULL;
m_pBottom = NULL;
m_nStackSize = 30;
}
~CStact() { //析构函数用于释放栈
if (m_pBottom != NULL) {
m_pBottom++;
delete[] m_pBottom; //delete[]释放 m_pBottom指向的内存
}
}
bool InitStack(int nStackSize) { //初始化栈方法
m_nStackSize = nStackSize; //给栈赋大小
try { //异常处理
m_pBottom = new type[m_nStackSize]; //建立栈空间内存
m_pBottom--; //m_pBottom指向栈底
m_pTop = m_pBottom; //m_pTop指向栈底,为空栈
}
catch (...) {
return false; //初始化失败返回false
}
return true; //栈初始化成功
}
bool Push(type *pNode) { //入栈方法
if (m_pTop - m_pBottom >= m_nStackSize || pNode == NULL) {
return false; //栈溢出或参数为空,入栈失败,返回false
}
m_pTop++; //栈顶指针上移
memcpy(m_pTop, pNode, sizeof(type)); //为栈顶赋值
return true;
}
bool Pop(type *pNode) { //出栈
if (m_pTop == m_pBottom) { //判断是否为空栈
return false;
}
memcpy(pNode, m_pTop, sizeof(type)); //将栈顶数据赋出
m_pTop--; //栈顶指针下移
return true;
}
bool GetTop(type *pNode) { //获取栈顶数据
if (m_pTop == m_pBottom) { //判断是否为空栈
return false;
}
memcpy(pNode, m_pTop, sizeof(type)); //将栈顶数据赋出
return true;
}
bool IsEmpty() { //判断栈是否为空栈方法
return (m_pTop == m_pBottom); //为空栈返回true
}
};
template<class Type> //定义二叉树模板
class CBinaryTree {
private:
Type* m_pRootNode; //根节点
int m_nNodeCount; //节点数目
public:
CBinaryTree() { //析构函数创建根节点并初始化二叉树
m_pRootNode = new Type();
m_nNodeCount = 1;
InitBinaryTree();
}
Type* GetRootNode() const { //获取根节点方法
return m_pRootNode;
}
void InitBinaryTree() { //初始化二叉树方法
Type* pTmpNode = m_pRootNode;
for (int i = 1;i <= 10;i++) { //创建10个节点
Type* pNode = new Type();
pNode->m_nData = i;
label:
bool bRet = AddNode(pTmpNode, pNode, 0); //添加左子节点,添加成功true,失败false
if (!bRet) { //添加左子节点失败
bRet = AddNode(pTmpNode, pNode, 1); //添加右子节点
}
if (!bRet) { //添加左右子节点均失败,即左右子节点均不为空
pTmpNode = pTmpNode->m_pLeftNode; //指针指向当前结点的左子节点
goto label;
}
}
}
void LoopBinaryTree() { //循环遍历二叉树方法
CStact<CNode> Stack; //定义一个栈
Stack.InitStack(m_nNodeCount); //初始化栈
Stack.Push(m_pRootNode); //根节点入栈
Type *pNode = m_pRootNode;
while (!Stack.IsEmpty()) { //判断栈是否不为空
if (pNode) { //判断该节点是否不为空
while (pNode) { //遍历该节点左子节点直到最后一个
Stack.Push(pNode->m_pLeftNode); //将该节点左子节点入栈
pNode = pNode->m_pLeftNode; //指针指向该节点左子节点
}
}
else //指针指向最后一个左子节点
{
Type Node;
bool bRet = Stack.Pop(&Node); //栈顶数据出栈,即最后一个左子节点出栈
if (bRet) {
cout << "节点数据" << Node.m_nData << endl; //输出最后一个左子节点数据
}
bRet = Stack.Pop(&Node); //栈顶数据出栈,即最后一个左子节点的父节点出栈
if (bRet) {
cout << "节点数据" << Node.m_nData << endl; //输出最后一个左子节点的父节点数据
}
if (bRet&&Node.m_pRightNode != NULL) { //最后一个左子节点的父节点的右子节点不为空
Stack.Push(Node.m_pRightNode); //将该右子节点入栈
pNode = Node.m_pRightNode; //指针指向该右子节点,并进行遍历
}
}
}
}
bool AddNode(Type* pDestation, Type* pNode, int nFlag = 0) { //添加节点方法,nFlag判断添加左右子节点
if (pDestation != NULL&&pNode != NULL) {
if (nFlag) { //nFlag=1,添加右子节点
if (!pDestation->m_pRightNode) { //判断右子节点是否为空,为空则添加
pDestation->m_pRightNode = pNode;
}
else {
return false; //添加失败返回false
}
}
else { //nFlag=0,添加左子节点
if (!pDestation->m_pLeftNode) { //判断左子节点是否为空,为空则添加
pDestation->m_pLeftNode = pNode;
}
else {
return false; //添加失败返回false
}
}
m_nNodeCount++; //添加成功节点数目加1
return true;
}
return false; //添加失败
}
void DestoryBinaryTree(Type* pNode) { //释放二叉树节点方法
Type *pLeftNode, *pRightNode;
if (pNode != NULL) { //需要释放的节点不为空
pLeftNode = pNode->m_pLeftNode; //pLeftNode指向当前结点左子节点
pRightNode = pNode->m_pRightNode; //pRightNode指向当前结点右子节点
delete pNode; //释放当前节点
pNode = NULL;
if (pLeftNode != NULL) { //判断当前结点左子节点是否不为空
DestoryBinaryTree(pLeftNode); //以当前结点左子节点作为父节点进行遍历释放
}
if (pRightNode != NULL) { //判断当前结点右子节点是否不为空
DestoryBinaryTree(pRightNode); //以当前结点右子节点作为父节点进行遍历释放
}
}
}
virtual ~CBinaryTree() { //析构函数用来释放二叉树节点
DestoryBinaryTree(m_pRootNode);
}
};
class CNode { //定义节点类型
private:
CNode *m_pLeftNode; //左子节点
CNode *m_pRightNode; //右子节点
int m_nData; //节点数据
public:
CNode() {
m_pLeftNode = NULL;
m_pRightNode = NULL;
m_nData = 0;
}
virtual ~CNode() {
m_pLeftNode = NULL;
m_pRightNode = NULL;
m_nData = 0;
}
friend class CBinaryTree<CNode>; //申明CBinaryTree为友元类
};
int main(int argc, char argv[]) {
CBinaryTree<CNode> BinaryTree;
BinaryTree.LoopBinaryTree();
return 0;
}