二叉树的非递归遍历和层次遍历

数据结构

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

测试数据:

猜你喜欢

转载自blog.csdn.net/qq_41317652/article/details/83661818