用遞歸的方法遍歷二叉樹很簡單,但是非遞歸的遍歷二叉樹就比較困難了。在非遞歸方法中,我們需要棧stack的幫助。以下是分別用遞歸方式和非遞歸方式寫的前、中、後序遍歷二叉樹的方法,經過驗證結果是正確的。
#include <iostream>
#include <stack>
using namespace std;
struct Node
{
int num;
Node* pLeft;
Node* pRight;
};
void insert(Node* &p,int num)
{
Node* pTmp=new Node();
pTmp->num=num;
pTmp->pLeft=pTmp->pRight=NULL;
if(p==NULL)
{
p=pTmp;
return;
}
if(num<p->num)
insert(p->pLeft,num);
else if(num>p->num)
insert(p->pRight,num);
else
return;
}
void PreOrder(Node* p)
{
if(p==NULL)
return;
else
{
cout<<p->num<<" ";
PreOrder(p->pLeft);
PreOrder(p->pRight);
}
}
void InOrder(Node* p)
{
if (p==NULL)
return;
else
{
InOrder(p->pLeft);
cout<<p->num<<" ";
InOrder(p->pRight);
}
}
void PostOrder(Node* p)
{
if (p==NULL)
return;
else
{
PostOrder(p->pLeft);
PostOrder(p->pRight);
cout<<p->num<<" ";
}
}
void PreOrderByLoop(Node* p)
{
stack<Node*> MyStack;
if(p==NULL)
return;
while(p!=NULL||!MyStack.empty()) //p和棧都爲空是結束循環的條件
{
while(p!=NULL)
{
MyStack.push(p);
cout<<p->num<<" ";
p=p->pLeft;
}
if(!MyStack.empty()) //從棧中取出一個節點的指針
{
p=MyStack.top();
MyStack.pop();
p=p->pRight; //當前節點的右孩子 當做一個子樹的根節點 從新開始循環
}
}
cout<<endl;
}
void InOrderByLoop(Node* p)
{
stack<Node*> Mystack;
while(p!=NULL||!Mystack.empty())
{
while(p!=NULL)
{
Mystack.push(p);
p=p->pLeft;
}
if(!Mystack.empty())
{
p=Mystack.top();
Mystack.pop();
cout<<p->num<<" ";
p=p->pRight;
}
}
cout<<endl;
}
void PostOrderByLoop(Node* p)
{
stack<Node*> Mystack;
Node* pre=NULL; //剛剛訪問過的節點
while(p!=NULL||!Mystack.empty())
{
while(p!=NULL)
{
Mystack.push(p);
p=p->pLeft;
}
p=Mystack.top();
if(p->pRight==NULL||p->pRight==pre) //沒有右孩子 或者右孩子剛剛遍歷過了
{
cout<<p->num<<" ";
Mystack.pop();
pre=p;
p=NULL; //加這一句是爲了跳過入棧那部分程序
}
else
p=p->pRight;
}
cout<<endl;
}
void main()
{
Node* p=NULL;
insert(p,10);
insert(p,6);
insert(p,14);
insert(p,4);
insert(p,8);
insert(p,12);
insert(p,16);
insert(p,1);
insert(p,5);
insert(p,15);
insert(p,17);
insert(p,7);
insert(p,9);
cout<<"Preorder:"<<endl;
PreOrder(p);
cout<<endl<<"preorderbyLoop:"<<endl;
PreOrderByLoop(p);
cout<<endl<<"Inorder:"<<endl;
InOrder(p);
cout<<endl<<"InorderbyLoop:"<<endl;
InOrderByLoop(p);
cout<<endl<<"Postorder:"<<endl;
PostOrder(p);
cout<<endl<<"PostOrderByLoop:"<<endl;
PostOrderByLoop(p);
}