首先 我们先来了解一下二叉树遍历的一些特性
二叉树的遍历分为前序遍历 ;中序遍历;后序遍历 ;
其中
前序遍历的顺序是 根 左 右
中序遍历的顺序是 左 根 右
后序遍历的顺序是 左 右 根
相关图形如下 方便理解
关于二叉树非递归形式的遍历
下面 我们要对这样一个二叉树进行定义并且遍历
首先 我们先定义二叉树的结构体
struct BinaryTree
{
int id;
BinaryTree* Left;
BinaryTree* Right;
};
然后我们在主函数中创建一个这样的二叉树
//根
BinaryTree* Boot = new BinaryTree;
Boot->id = 1;
//根的左
Boot->Left = new BinaryTree;
Boot->Left->id = 2;
//根的左的左
Boot->Left->Left = new BinaryTree;
Boot->Left->Left->id = 4;
Boot->Left->Left->Left = NULL;
Boot->Left->Left->Right = NULL;
//左的右
Boot->Left->Right = new BinaryTree;
Boot->Left->Right->id = 5;
Boot->Left->Right->Left = NULL;
Boot->Left->Right->Right = NULL;
//根的右
Boot->Right = new BinaryTree;
Boot->Right->id = 3;
//右的左
Boot->Right->Left = new BinaryTree;
Boot->Right->Left->id = 6;
Boot->Right->Left->Left = NULL;
Boot->Right->Left->Right = NULL;
//右的右
Boot->Right->Right = new BinaryTree;
Boot->Right->Right->id = 7;
Boot->Right->Right->Left = NULL;
Boot->Right->Right->Right = NULL;
之后 我们开始进行对二叉树的遍历方法的编写
前序遍历:
这里用到了栈作为遍历方法的工具
所以我们引入头文件
#include<stack>
//前序遍历
void qianxubianli(BinaryTree*pRoot)
{
//判断当前树是否为空
if (NULL == pRoot)
return;
//定义一个栈用作工具
stack<BinaryTree*>st;
while (1)
{
//
while (pRoot)
{
//打印当前节点并入栈
cout << pRoot->id << " ";
st.push(pRoot);
//向左走
pRoot = pRoot->Left;
}
//左为空 判断当前栈是否为空 为空则遍历结束
if (st.empty() == true)
{
cout << endl;
return;
}
pRoot = st.top();
//出栈
st.pop();
//向右走
pRoot = pRoot->Right;
}
}
中序遍历:
和前序遍历区别不大 只是打印的位置不同
//中序遍历
void zhongxubianli(BinaryTree* pRoot)
{
if (NULL == pRoot)
return;
stack<BinaryTree*>st;
while (1)
{
while (pRoot)
{
st.push(pRoot);
pRoot = pRoot->Left;
}
if (st.empty() == true)
{
cout << endl;
return;
}
pRoot = st.top();
st.pop();
cout << pRoot->id << " ";
pRoot = pRoot->Right;
}
}
后序遍历:
相对较复杂
前面的while(pRoot)大体相同
在处理出栈时有所不同而且需要设置一个标记来作为出栈的判断条件所使用的工具之一
BinaryTree* pMark = NULL;
pMark的作用主要是用来判断当前节点的右是否被处理过
pMark的作用是用来记录上一个被处理的节点
所以在出栈时 我们 对pMark进行赋值为出栈的节点
如果没有"//判断当前栈顶元素的右是否被标记"这一判断条件 程序将会出现死循环
//后序遍历
void houxubianli(BinaryTree* pRoot)
{
if (NULL == pRoot)
return;
stack<BinaryTree*>st;
BinaryTree* pMark = NULL;
while (1)
{
while (pRoot)
{
st.push(pRoot);
pRoot = pRoot->Left;
}
if (st.empty() == true)
{
cout << endl;
return;
}
//判断当前栈顶元素的右是否被标记 或当 前栈顶元素是否有右
if (st.top()->Right == NULL || st.top()->Right == pMark)
{
pMark = st.top();
st.pop();
cout << pMark->id << " ";
}
//执行当前元素的右
else
{
pRoot = st.top();
pRoot = pRoot->Right;
}
}
}
完整代码如下
#include<iostream>
#include<stack>
#include<stdlib.h>
#include<queue>
using namespace std;
struct BinaryTree
{
int id;
BinaryTree* Left;
BinaryTree* Right;
};
//前序遍历
void qianxubianli(BinaryTree*pRoot)
{
//判断当前树是否为空
if (NULL == pRoot)
return;
//定义一个栈用作工具
stack<BinaryTree*>st;
while (1)
{
//
while (pRoot)
{
//打印当前节点并入栈
cout << pRoot->id << " ";
st.push(pRoot);
pRoot = pRoot->Left;
}
//左为空 判断当前栈是否为空 为空则遍历结束
if (st.empty() == true)
{
cout << endl;
return;
}
pRoot = st.top();
st.pop();
pRoot = pRoot->Right;
}
}
//中序遍历
void zhongxubianli(BinaryTree* pRoot)
{
if (NULL == pRoot)
return;
stack<BinaryTree*>st;
while (1)
{
while (pRoot)
{
st.push(pRoot);
pRoot = pRoot->Left;
}
if (st.empty() == true)
{
cout << endl;
return;
}
pRoot = st.top();
st.pop();
cout << pRoot->id << " ";
pRoot = pRoot->Right;
}
}
//后序遍历
void houxubianli(BinaryTree* pRoot)
{
if (NULL == pRoot)
return;
stack<BinaryTree*>st;
BinaryTree* pMark = NULL;
while (1)
{
while (pRoot)
{
st.push(pRoot);
pRoot = pRoot->Left;
}
if (st.empty() == true)
{
cout << endl;
return;
}
//判断当前栈顶元素的右是否被标记 或当 前栈顶元素是否有右
if (st.top()->Right == NULL || st.top()->Right == pMark)
{
pMark = st.top();
st.pop();
cout << pMark->id << " ";
}
//执行当前元素的右
else
{
pRoot = st.top();
pRoot = pRoot->Right;
}
}
}
//程序遍历
void chengxubianli(BinaryTree* pRoot)
{
if (NULL == pRoot)
{
return;
}
queue<BinaryTree*> Qu;
Qu.push(pRoot);
while (Qu.empty()==0)
{
pRoot=Qu.front();
Qu.pop();
if (pRoot!=NULL)
{
cout << pRoot->id << " ";
Qu.push(pRoot->Right);
Qu.push(pRoot->Left);
}
}
cout << endl;
}
int main()
{
//根
BinaryTree* Boot = new BinaryTree;
Boot->id = 1;
//根的左
Boot->Left = new BinaryTree;
Boot->Left->id = 2;
//根的左的左
Boot->Left->Left = new BinaryTree;
Boot->Left->Left->id = 4;
Boot->Left->Left->Left = NULL;
Boot->Left->Left->Right = NULL;
//左的右
Boot->Left->Right = new BinaryTree;
Boot->Left->Right->id = 5;
Boot->Left->Right->Left = NULL;
Boot->Left->Right->Right = NULL;
//根的右
Boot->Right = new BinaryTree;
Boot->Right->id = 3;
//右的左
Boot->Right->Left = new BinaryTree;
Boot->Right->Left->id = 6;
Boot->Right->Left->Left = NULL;
Boot->Right->Left->Right = NULL;
//右的右
Boot->Right->Right = new BinaryTree;
Boot->Right->Right->id = 7;
Boot->Right->Right->Left = NULL;
Boot->Right->Right->Right = NULL;
qianxubianli(Boot);
zhongxubianli(Boot);
houxubianli(Boot);
chengxubianli(Boot);
return 0;
}
执行结果如图: