Non-recursive binary tree traversal

About half of large data structures

Knowledge Point

Recursive algorithm is simple, but in general, its implementation is not very efficient. For the binary tree traversal operations, during the execution of the recursive algorithm can be modeled in the working state change of the stack to obtain a non recursive algorithm.
First, a non-recursive algorithm preorder traversal
key preorder before non-recursive algorithm is a binary tree: pre-order traversing through the entire left subtree of a node, the pointer is how to find the root node of the right subtree for a FIG. binary
Here Insert Picture Description
production stack S and the current root pointer bt changes and access order of each node in the tree.
Here Insert Picture Description

分析二叉树前序遍历的执行过程可以看出,在访问某结点后,应将该结点的指针保存在栈中,以便以后能通过它找到
该结点的右子树。一般情况下,在前序遍历中,设要遍历二叉树的根指针为bt,可能有两种情况:
(1)若bt!=NULL,则表明当前二叉树不为空,此时,应输出根结点bt的值并将bt保存到栈中,准备继续遍历bt的
左子树。
(2)若bt==NULL,则表明以bt为根指针的二叉树遍历完毕,并且bt是栈顶指针所指结点的左子树。若栈不为空,应根据栈顶指针所指结点找到待遍历右子树的根指针并赋予bt,以继续遍历下去:若栈为空,则表明整个二叉树遍历完毕,应结束。

Non-recursive algorithm before traversing Binary Tree

void PreorderTraversal(  BiNode *root )//( BinTree BT )BinTree 为结构体指针,BiNode 为结构体类型
                                                          //二叉链表的根指针root
{
	BiNode *bt=root,*S[MaxSize];//定义顺序栈,工作指针bt初始化
	int top=-1;//初始化顺序栈
	while(bt!=NULL||top!=-1)//两个条件都不成立才退出循环
	{
		while(bt!=NULL)//当bt不空时循环
		{
			printf(" %c",bt->Data);//输出bt->data
			S[++top]=bt;//将指针bt保存到栈中
			bt=bt->lchild;//遍历bt的左子树
		}
		if(top!=-1)如果栈S不空,则
		{
			bt=S[top--];//将栈顶元素弹出至bt
			bt=bt->rchild;//准备遍历bt的右子树
		}
	
	}
}
void PreorderTraversal( BinTree BT )
{
    Stack s=CreateStack();
       //Push(s,BT);  
      BinTree now=BT;    
      if(now!=NULL)        
      Push(s,now);   
       while(!IsEmpty(s))
       {        now=Pop(s);        
                printf(" %c",now->Data);
                if(now->Right!=NULL)            
                Push(s,now->Right);
                if(now->Left!=NULL)     
                Push(s,now->Left);    
       }
}

In order traversal non-recursive algorithm
encounters a node can not access it immediately, but will push it until after its left sub-tree traversal is complete, then popped from the stack and access it in order traversal process.

void InorderTraversal( BiNode *root  )//( BinTree BT )BinTree 为结构体指针,BiNode 为结构体类型
                                                          //二叉链表的根指针root
{
	BiNode *bt=root,*S[MaxSize];//定义顺序栈,工作指针bt初始化
	int top=-1;//初始化顺序栈
	while(bt!=NULL||top!=-1)//两个条件都不成立才退出循环
	{
		while(bt!=NULL)//当bt不空时循环
		{
			S[++top]=bt;//将指针bt保存到栈中
			bt=bt->lchild;//遍历bt的左子树
		}
		if(top!=-1)如果栈S不空,则
		{
			bt=S[top--];//将栈顶元素弹出至bt
			printf(" %c",bt->Data);//输出bt->data
			bt=bt->rchild;//准备遍历bt的右子树
		}
	
	}
}
void InorderTraversal( BinTree BT )
{        Stack s=CreateStack();
          if(BT!=NULL)      
          Push(s,BT);
          BinTree now; 
          while(!IsEmpty(s))
          {        while(Peek(s)->Left!=NULL)            
                   Push(s,Peek(s)->Left);        
                   while(!IsEmpty(s))
                   {            now=Peek(s);            
                                printf(" %c",now->Data);            
                                Pop(s);            
                                if(now->Right!=NULL)
                                {            Push(s,now->Right); 
                                              break;            
                                 }        
                    }    
           }
}

Postorder non-recursive algorithms
when traversed left subtree, since the traverse right subtree yet, so the pull stack node can not find its right subtree node through the stack, it is ready to traverse the right subtree: when After traversing the right subtree, the top of the stack the stack node, and access to it.
In order to distinguish between different nodes handling of the stack, sets the flag variable flag, flag = 1 indicates the left subtree been traversed, the stack can not stack node: flag = 2 indicates traversed right subtree, the nodes may be the top of the stack stack and access. Stack element type can be defined by the type of structure c language

typedef struct{
BiNode *ptr;
int flag;
}ElemType;//BiNode 为结构体类型

To traverse the binary tree root pointer set for bt, there are the following two situations:
(1) if bt is not equal to NULL, then bt In Flag and flag (set to 1) onto the stack, as it traverses its left subtree.
(2) if bt is equal to NULL, the stack is empty at this time, the entire iteration is complete: If the stack is not empty, the top of the stack node or left subtree right subtree is traversed completed. If the flag FLAG = 1 stack node, it indicates that the left subtree of nodes to traverse the stack is completed, the flag to 2, and traverse right subtree node stack: the stack if the node flag Flag = 2, it indicates that the stack node can traverse right subtree is complete, the pull stack and the output node.

void PostorderTraversal(BiNode *root )
{
	ElemType S[MaxSize];//定义顺序栈
	int top=-1;初始化顺序栈
	BiNode *bt=root;//工作指针bt初始化
	while(bt!=NULL||top!=-1)//循环直到bt为空且栈S为空
	{
		while(bt!=NULL)
		{
			top++;
			S[top].ptr=bt;//root连同标志flag入栈
			S[top].flag=1;
			bt=bt->lchild;//继续遍历bt的左子树
		}
		while(top!=-1&&S[top].flag==2)//注意是循环,可能连续出栈
		//当栈S非空且栈顶元素的标志为2时,出栈并输出栈顶结点
		{
			bt=S[top--].ptr;
			printf(" %c",bt->Data);
		}
		if(top!=-1)//当栈非空,将栈顶元素的标志改为2,准备遍历栈顶结点的右子树
		{
			S[top].flag=2;
			bt=S[top].ptr->rchild;
		}
	}
 } 
void PostorderTraversal( BinTree BT )
{    Stack s=CreateStack();
    if(BT!=NULL)        
    Push(s,BT);    
    BinTree now=BT,last=NULL;
    while(!IsEmpty(s))
     {        while(Peek(s)->Left!=NULL)            
               Push(s,Peek(s)->Left);        
               while(!IsEmpty(s))
               {            now=Peek(s);            
                            if(now->Right==last||now->Right==NULL)
                            {               printf(" %c",now->Data);
                                            Pop(s);
                                           last=now;
                              }            
                              else
                              {                Push(s,now->Right);  
                                               break;            
                               }        
                }  
    }
}

Add a link description
attached great God blog address

Published 46 original articles · won praise 16 · views 9455

Guess you like

Origin blog.csdn.net/weixin_43717681/article/details/89191772