二叉树利用堆栈实现遍历的非递归算法

版权声明:本文为博主(拉风小宇)原创文章,转载请标明出处(或者大力打广告哈哈)。 https://blog.csdn.net/lafengxiaoyu/article/details/53218104

二叉树的遍历有三种不同的遍历方法,分别是前序遍历、中序遍历以及后序遍历

遍历的实现我们在上一篇博客中已经用递归的方法实现了,那么可不可以不用递归实现呢,答案是可以的

在这一篇博客中我们会利用堆栈将遍历改为非递归 

下面先附上实现的代码

#include "stdio.h"  
#include "stdlib.h"    

typedef struct tree
{  
    char data;  
    struct tree *lchild;  
    struct tree *rchild;  
 }*Ptree; 

typedef Ptree ElementType;


typedef struct SNode *Stack;  
struct SNode{  
    ElementType Data;  
    struct SNode *Next;  
}; 


Stack CreateStack();  
//判断是否空  
int IsEmpty(Stack S);  
//Push操作  
void Push(ElementType item,Stack S);  
//Pop操作  
ElementType Pop(Stack S);  

//树的建立
 Ptree createTree() ;
 //先序遍历 
void preOrder(Ptree t);
//中序遍历  
void intOrder(Ptree t);  
//后序遍历  
void postOrder(Ptree t);  

//利用栈先序遍历二叉树
void PreOderTraversal(Ptree BT);
//利用栈中序遍历二叉树
void InOderTraversal(Ptree BT);
 //利用栈后序遍历
void PostOderTraversal(Ptree BT);
//利用双栈法后序遍历
void PostOderTraversal2(Ptree BT);



void main()  
{   
   Ptree t; 
   printf("先序创建二叉树,用空格代表虚结点:\n");
   t=createTree(); 
   printf("前序遍历:");
   preOrder(t) ;
   printf("\n");
   printf("利用堆栈前序遍历:");
   PreOderTraversal(t);
   printf("\n");
   printf("\n");

   printf("中序遍历:");
   intOrder(t) ;
   printf("\n");
   printf("利用堆栈中序遍历:");
   InOderTraversal(t);
   printf("\n");
   printf("\n");

   printf("后序遍历:");
   postOrder(t) ;
   printf("\n");
   printf("利用堆栈后序遍历:");
   PostOderTraversal(t);
   printf("\n");
   printf("利用双栈法后序遍历:");
   PostOderTraversal2(t);

   system("pause");
}


 
//堆栈的建立  
Stack CreateStack(){  
    Stack S;  
    S=(Stack)malloc(sizeof(struct SNode));  
    S->Next=NULL;  
    return S;  
}  
//判断是否空  
int IsEmpty(Stack S){  
    return(S->Next==NULL);  
}  
//Push操作  
void Push(ElementType item,Stack S){  
    struct SNode *TmpCell;  
    TmpCell=(struct SNode *)malloc(sizeof(struct SNode));  
    TmpCell->Data=item;  
    TmpCell->Next=S->Next;  
    S->Next=TmpCell;  
}  

//Pop操作
ElementType Pop(Stack S){  
    struct SNode *FirstCell;  
    ElementType TopElem;  
    if(IsEmpty(S)){  
        printf("堆栈空\n");  
        return NULL;  
    }else{  
        FirstCell=S->Next;  
        S->Next=FirstCell->Next;  
        TopElem=FirstCell->Data;  
        free(FirstCell);  
        return TopElem;  
    }  
}  






 Ptree createTree()   //树的建立
 {  
     char ch;  
     Ptree t;  
     ch=getchar();  //输入二叉树数据
     if(ch==' ')  //判断二叉树是否为空
         t=NULL;  
     else 
     {  
         t=(Ptree)malloc(sizeof(Ptree));  //二叉树的生成
         t->data=ch;  
         t->lchild=createTree();  
         t->rchild=createTree();  
     }  
     return t;  
 }  
 
 void preOrder(Ptree t)  //先序遍历 
 {  
     if(t)  
     {    
         printf("%c",t->data);  
         preOrder(t->lchild);  
         preOrder(t->rchild);  
     }  
 }  
 
 void intOrder(Ptree t)  //中序遍历  
{  
    if(t)  
     {  
        intOrder(t->lchild);  
        printf("%c",t->data);  
        intOrder(t->rchild);  
     }  
 }  
 
 void postOrder(Ptree t)  //后序遍历  
 {  
     if(t)  
     {     
         postOrder(t->lchild);  
         postOrder(t->rchild); 
	     printf("%c",t->data);  
     }  
 } 

  //利用栈先序遍历
 void PreOderTraversal(Ptree BT){
	 Ptree T=BT;
	 Stack S=CreateStack();
	 while(T||!IsEmpty(S)){
		 while(T){ 
			 printf("%c",T->data);
			 Push(T,S);
			 T=T->lchild;
		 }
			 T=Pop(S);
			 T=T->rchild;
	 }
 };

 //利用栈中序遍历
 void InOderTraversal(Ptree BT){
	 Ptree T=BT;
	 Stack S=CreateStack();
	 while(T||!IsEmpty(S)){
		 while(T){
			 Push(T,S);
			 T=T->lchild;
		 }
			 T=Pop(S);
			 printf("%c",T->data);
			 T=T->rchild;
	 }
 };

  //利用栈后序遍历
 void PostOderTraversal(Ptree BT){
	 Ptree T=BT;
	 Ptree TempT=NULL;//Temp记录被检查的节点的右儿子
	 Stack S=CreateStack();
	 while(T||!IsEmpty(S)){
		 while(T){
			 Push(T,S);
			 T=T->lchild;
		 }
		 T=Pop(S);Push(T,S);//相当于返回了栈顶元素
		  // 当前节点的右孩子如果为空或者已经被访问,则访问当前节点    
	    if(T->rchild==NULL||T->rchild==TempT){
            printf("%c",T->data);
			TempT=T;
			Pop(S);
			T=NULL;
		}
		 // 否则访问右孩子 
		else
		    T=T->rchild;			
	 }
 };


//利用双栈法后序遍历
void PostOderTraversal2(Ptree BT) // 后序遍历的非递归     双栈法    
{   
	Ptree T=BT; // 指向当前要检查的节点  
    Stack S1=CreateStack();
	Stack S2=CreateStack();            
    Push(T,S1);    
    while(!IsEmpty(S1))  // 栈空时结束      
    {    
        T = Pop(S1);
		Push(T,S2);  
        if(T->lchild)
			Push(T->lchild,S1);    
        if(T->rchild)    
            Push(T->rchild,S1);    
    }    
    while(!IsEmpty(S2))    
    {   
        printf("%c", Pop(S2)->data);      
    }    
}    
其中栈的后序非递归遍历参考了一篇网上的博客,用了两种方法实现了后序遍历

下面是一个具体实现的例子

树是这样的,如下

                   A

       B                  C

D         F      G           I

         E             H

前序输入的时候是

ABD##FE###CG#H##I##

执行的结果如下


我只有一个感受。。好厉害。。。

阅读更多
换一批

没有更多推荐了,返回首页