数据结构
struct node{
int val;
node *lchild,*rchild;
};
先序非递归遍历
1) 访问结点p,并将结点P入栈;
2) 判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,
并将栈顶结点的右孩子置为当前的结点P,循环->1;若不为空,则将P的左孩子置为当前的结点P;
3) 直到P为NULL并且栈为空,则遍历结束。
void PreOrder(node *root){
if(!root) return ;
node *p=root;
stack<node *> s;
while(p || !s.empty()){
while(p){
visit(p);
s.push(p);
p=p->lchild ;
}
if(!s.empty()){
p=s.top() ;
s.pop() ;
p=p->rchild;
}
}
}
中序非递归遍历
1) 先扫描(并非访问)根的所有左结点并将他们一一入栈,
2)然后出栈一个结点*p(显然*p没有左孩子或者左孩子结点均已经访问)
则访问它,然后扫描该结点右孩子,将其入栈,再扫描右孩子的所有左结点并一一入栈,如此继续,直至栈空
void InOrder(node *root){
if(!root) return;
node *p=root;
stack<node *> s;
while(p || !s.empty()){ //栈不为空或p不为空
while(p){
s.push(p); //根指针入栈,并遍历左子树
p=p->lchild ;
}
if(!s.empty()){
p=s.top() ; //根指针退栈,访问根节点,遍历右子树
s.pop() ;
visit(p);
p=p->rchild;
}
}
后续非递归遍历
后续非递归遍历二叉树的顺序是先变遍历左子树,再遍历右子树,最后遍历根结点。因此一个结点被访问的前提是无右子树或者右子树已经被访问,使用辅助指针LastVisit,指向最近访问过的结点,用pCur指向当前结点。
void PostOrder(node *root){
if(!root) return ;
stack<node *> s;
node *pCur=root,*LastVisit=NULL;
while(pCur){ //左子树全入栈
s.push(pCur);
pCur=pCur->lchild ;
}
while(!s.empty()){
pCur=s.top() ;
s.pop();
if(pCur->lchild ==NULL || pCur->rchild ==LastVisit){ //无右子树或根节点已被访问
visit(pCur);
LastVisit=pCur;
}
else{
s.push(pCur);
pCur=pCur->rchild ;
while(pCur){
s.push(pCur);
pCur=pCur->lchild ;
}
}//else
}//while
}
层次遍历
借助队列来实现
1)二叉树的根节点入队,然后出队并访问
如果他有左子树,左子树根节点入队,如果有右子树,右子树根节点入队,然后出队,访问出队结点
2)如此反复,直至队列为空
void BFS(node *root){
if(!root) return ;
node *p=root;
queue<node *>q;
q.push(root);
while(!q.empty()){
p=q.front() ;
q.pop();
visit(p);
if(p->lchild!=NULL) q.push(p->lchild );
if(p->rchild!=NULL) q.push(p->rchild );
}
}
完整代码:
#include<iostream>
#include<queue>
#include<stack>
using namespace std;
struct node{
int val;
node *lchild,*rchild;
};
void visit(node *root){
cout<<root->val <<" ";
}
void PreOrder(node *root){
if(!root) return ;
node *p=root;
stack<node *> s;
while(p || !s.empty()){
while(p){
visit(p);
s.push(p);
p=p->lchild ;
}
if(!s.empty()){
p=s.top() ;
s.pop() ;
p=p->rchild;
}
}
}
void InOrder(node *root){
if(!root) return;
node *p=root;
stack<node *> s;
while(p || !s.empty()){
while(p){
s.push(p);
p=p->lchild ;
}
if(!s.empty()){
p=s.top() ;
s.pop() ;
visit(p);
p=p->rchild;
}
}
}
void PostOrder(node *root){
if(!root) return ;
stack<node *> s;
node *pCur=root,*LastVisit=NULL;
while(pCur){
s.push(pCur);
pCur=pCur->lchild ;
}
while(!s.empty()){
pCur=s.top() ;
s.pop();
if(pCur->lchild ==NULL || pCur->rchild ==LastVisit){
visit(pCur);
LastVisit=pCur;
}
else{
s.push(pCur);
pCur=pCur->rchild ;
while(pCur){
s.push(pCur);
pCur=pCur->lchild ;
}
}//else
}//while
}
void BFS(node *root){
if(!root) return ;
node *p=root;
queue<node *>q;
q.push(root);
while(!q.empty()){
p=q.front() ;
q.pop();
visit(p);
if(p->lchild!=NULL) q.push(p->lchild );
if(p->rchild!=NULL) q.push(p->rchild );
}
}
int main(){
node *root=new node;
root->val=1;
root->lchild=new node;
root->rchild=new node;
root->lchild->val=2;
root->rchild->val=3;
root->lchild->lchild=new node;
root->lchild->rchild=new node;
root->lchild->lchild->val =4;
root->lchild->rchild->val =5;
root->lchild->lchild->lchild=NULL;
root->lchild->lchild->rchild=NULL;
root->lchild->rchild->lchild=NULL;
root->lchild->rchild->rchild=NULL;
root->rchild->lchild=NULL;
root->rchild->rchild=NULL;
cout<<" 先序非递归遍历: " ;
PreOrder(root);
cout<<endl;
cout<<" 中序非递归遍历: ";
InOrder(root);
cout<<endl;
cout<<" 后序非递归遍历: ";
PostOrder(root);
cout<<endl;
cout<<" 层次遍历: ";
BFS(root);
cout<<endl;
}
测试数据: