二叉树的非递归遍历用到栈这个数据结构前序中序,度比较简单,但是在后序遍历时因为我们先打印子节点数据,此时该节点还不能删除,因为我们还要通过它得到右节点,所以删除一个节点的条件是该节点没有左右孩子,或是访问到该节点时,前一个节点应该是该节点的左右孩子其中的一个,这个表名这个节点的孩子节点之前已经访问了,现在该访问该节点啦。
附上源代码
#include <stdio.h>
#include <stdlib.h>
#include <stack>
#include <iostream>
using namespace std;
#define OVERFLOW 0
struct BiTree{
char data;
BiTree *LChild;
BiTree *RChild;
};
//先序创建二叉树的递归方法
void Create_BiTree_ByPrev_2(BiTree** T)
{
char ch;
scanf("%c",&ch);
if(ch=='#')
{
*T=NULL;
}else{
*T=(BiTree*)malloc(sizeof(BiTree));
if(!*T)
{
exit(OVERFLOW);
}
(*T)->data=ch;
Create_BiTree_ByPrev_2(&(*T)->LChild);
Create_BiTree_ByPrev_2(&(*T)->RChild);
}
}
//中序的非递归
void MediumTransver_ByStack(BiTree* T)
{
stack<BiTree*> Sta;
BiTree* pTmp=NULL;
Sta.push(T);//根节点入栈
while(!Sta.empty())//若栈为空表名二叉树已经遍历完
{
while(Sta.top())
{
Sta.push(Sta.top()->LChild);
}
//表名已经到了最左端的结点的子节点,该节点为空,我们要出栈
Sta.pop();
if(Sta.empty()) return;
pTmp=Sta.top();//得到最左边的结点
printf("%c",pTmp->data);
Sta.pop();//从栈中删掉
//这个时候表名已经遍历到最左子树的中间结点(因为左子树为空,不输出,我们要讲右子树入栈)
Sta.push(pTmp->RChild);
}
}
//后序的非递归遍历方法
void PostTransver_ByStack(BiTree* T)
{
stack<BiTree*> s;
BiTree *cur; //当前结点
BiTree *pre=NULL; //前一次访问的结点
s.push(T);
while (!s.empty())
{
//只有当前节点的左右孩子为空才可以从栈中删除,或是前一个访问节点是孩子节点才可以在栈中删除
cur=s.top();
if((cur->LChild==NULL&&cur->RChild==NULL)||
(pre!=NULL&&(pre==cur->LChild||pre==cur->RChild)))
{
cout<<cur->data<<" "; //如果当前结点没有孩子结点或者孩子节点都已被访问过
s.pop();
pre=cur;
}
else
{
if(cur->RChild!=NULL)
s.push(cur->RChild);
if(cur->LChild!=NULL)
s.push(cur->LChild);
}
}
}
//前序遍历的非递归
void PrevTransver_ByStack(BiTree* T)
{
stack<BiTree*>sta;
BiTree *p=T;
while(p!=NULL||!sta.empty())
{
while(p!=NULL)
{
cout<<p->data<<" ";
sta.push(p);
p=p->LChild;
}
//此时第一到这的最左边的结点(而且没有左节点)
if(!sta.empty())
{
p=sta.top();
sta.pop();
p=p->RChild;
}
}
}
void main()
{
BiTree * pRootTree=NULL;
printf("请输入结点信息,空节点用#表示\n");
Create_BiTree_ByPrev_2(&pRootTree);
printf("中序遍历非递归方法\n");
MediumTransver_ByStack(pRootTree);
printf("前序遍历非递归方法\n");
PrevTransver_ByStack(pRootTree);
printf("后序遍历的非递归方法\n");
PostTransver_ByStack(pRootTree);
system("pause");
}