您的位置:首页 > 编程语言

递归、循环遍历二叉树代码实例

2017-04-10 00:00 447 查看
递归遍历二叉树
#include<iostream>

#include<memory.h>

using namespace std;

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 IterateBinaryTree(Type* pNode) { //递归遍历二叉树

if (pNode != NULL) { //判断当前结点是否不为空

cout << "节点数据" << pNode->m_nData << endl;

}

if (pNode->m_pLeftNode != NULL) { //判断当前结点左子节点是否不为空

IterateBinaryTree(pNode->m_pLeftNode); //从当前结点左子节点开始遍历

}

if (pNode->m_pRightNode != NULL) { //判断当前结点右子节点是否不为空

IterateBinaryTree(pNode->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.IterateBinaryTree(BinaryTree.GetRootNode());

return 0;

}



-------------------------------------------------------------------------------------------------------------
-----------------分割线-----------------------分割线--------------------分割线----------------------------
-------------------------------------------------------------------------------------------------------------
递归遍历二叉树

#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;

}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  IT C++