【100题】第四十二题 二叉树的非递归遍历

一,前序遍历非递归:

       根据前序遍历访问的顺序,优先访问根结点,然后再分别访问左孩子和右孩子。即对于任一结点,其可看做是根结点,因此可以直接访问,访问完之后,若其左孩子不为空,按相同规则访问它的左子树;当访问其左子树时,再访问它的右子树。因此其处理过程如下:

        对于任一结点P:

           1)访问结点P,并将结点P入栈;

           2)判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,循环至1);若不为空,则将P的左孩子置为当前的结点P;

           3)直到P为NULL并且栈为空,则遍历结束。

void preOrder2(node *root)     //非递归前序遍历

{

    stack<node*> s;

    node *p=root;

    while(p!=NULL||!s.empty())

    {

        while(p!=NULL)//向左遍历直到叶子

        {

            cout<<p->data<<" ";

            s.push(p);

            p=p->lchild;

        }

        if(!s.empty())

        {

            p=s.top();

            s.pop();

            p=p->rchild;

        }

    }

    cout<<endl;

}

二,中序遍历非递归

 

      根据中序遍历的顺序,对于任一结点,优先访问其左孩子,而左孩子结点又可以看做一根结点,然后继续访问其左孩子结点,直到遇到左孩子结点为空的结点才进行访问,然后按相同的规则访问其右子树。因此其处理过程如下:

      对于任一结点P,

           1)若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P,然后对当前结点P再进行相同的处理;

           2)若其左孩子为空,则取栈顶元素并进行出栈操作,访问该栈顶结点,然后将当前的P置为栈顶结点的右孩子;

           3)直到P为NULL并且栈为空则遍历结束

void inOrder2(node *root)      //非递归中序遍历

{

    stack<node*> s;

    node *p=root;

    while(p!=NULL||!s.empty())

    {

        while(p!=NULL)//记录访问过的根节点

        {

            s.push(p);

            p=p->lchild;

        }

        if(!s.empty())

        {

            p=s.top();

            cout<<p->data<<" "; //访问栈顶

            s.pop();

            p=p->rchild;  //将当前访问的元素的右孩子入栈

        }

    }   

}

 

            要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。

 

void postOrder3(node *root)     //非递归后序遍历

{

    stack<node*> s;

    node *cur;                      //当前结点

    node *pre=NULL;                 //前一次访问的结点

    s.push(root);

    while(!s.empty())

    {

        cur=s.top();

        if((cur->lchild==NULL&&cur->rchild==NULL)||

           (pre!=NULL&&(pre==cur->lchild||pre==cur->rchild)))

          {

            cout<<cur->data<<" ";  //如果当前结点没有孩子结点或者孩子节点都已被访问过

              s.pop();

            pre=cur;

         }

        else

        {

            if(cur->rchild!=NULL)

                s.push(cur->rchild);

            if(cur->lchild!=NULL)   

                s.push(cur->lchild);

        }

    }   

}

 

综合程序附录

#include "stdio.h"
#include "stdlib.h" 
#include "stack.h"
int count;//统计叶子节点个数 
struct node
{
	int data;//二叉树的节点值
	node *lchild,*rchild;//左右孩子节点 
};
/*不知道为什么 创建的时候需要返回值才 创建有效*/
node *createTree()
{
	node *root;
	int data;
	printf("input data:");
	scanf("%d",&data);
	//printf("output data:%d\n",data);
	
	if(data==0)
	  root=NULL;
    else/*根左右 前序建立二叉树*/
    {
    	root=(node*)malloc(sizeof(node));
    	root->data=data;
    	root->lchild=createTree();
    	root->rchild=createTree();	
    }
	return root;
} 
void preOrder(node *root)
{
	if(root==NULL)
       	 return;
	else//不是空
	{
		printf("%d\n",root->data);
		preOrder(root->lchild);
		preOrder(root->rchild); 
	} 

}
void inOrder(node *root)
{
	if(root==NULL)
       	 return;
	else//不是空
	{
		
		inOrder(root->lchild);
		printf("%d\n",root->data);
		inOrder(root->rchild); 
	} 

}
void postOrder(node *root)
{
	if(root==NULL)
       	 return;
	else//不是空
	{
		postOrder(root->lchild);
		postOrder(root->rchild);
		printf("%d\n",root->data); 
	} 

}
void  CountLeaves(node *root)
{
	if(root==NULL)
       	 return;
	else//不是空
	{
		if(root->lchild==NULL&&root->rchild==NULL)
		     count++;
		CountLeaves(root->lchild);
		CountLeaves(root->rchild); 
	} 
	
} 
int deepLength(node *root)
{
	int deep1,deep2;
	if(root==NULL)
	    return 0;
    else
    {
    	deep1=deepLength(root->lchild);
    	deep2=deepLength(root->rchild);
    	if(deep1>deep2)
    	     return deep1+1;//这个地方一定是返回+1 
        else
             return deep2+1;
    }
	
}
void  CountNodes(node *root)
{
	if(root==NULL)
       	 return;
	else//不是空
	{		
        count++;
		CountNodes(root->lchild);
		CountNodes(root->rchild); 
	} 
	
} 
void exchange(node *root)
{
	
	if(root==NULL)
	   return;
    else
    {
    	exchange(root->lchild);
    	exchange(root->rchild);
    	node *temp=root->lchild;
    	root->lchild=root->rchild;
    	root->rchild=temp;
    	
    }
}
void search(node *root,int x)
{

	if(root==NULL)
	    return ;
    else
       {
       	  if(root->data==x)
       	     {
     	       	count++;  
     	       	printf("has\n");
     	       }      
   	      search(root->lchild,x);
	      search(root->rchild,x);
       }
}

void preOrder2(node *root)     //非递归前序遍历 
{
    stack<node*> s;
    node *p=root;
    while(p!=NULL||!s.empty())
    {
        while(p!=NULL)//向左遍历 直到叶子 
        {
            cout<<p->data<<" ";
            s.push(p);
            p=p->lchild;
        }
        if(!s.empty())
        {
            p=s.top();
            s.pop();
            p=p->rchild;
        }
    }
    cout<<endl; 
}
void inOrder2(node *root)      //非递归中序遍历
{
    stack<node*> s;
    node *p=root;
    while(p!=NULL||!s.empty())
    {
        while(p!=NULL)
        {
            s.push(p);
            p=p->lchild;
        }
        if(!s.empty())
        {
            p=s.top();
            cout<<p->data<<" ";
            s.pop();
            p=p->rchild;
        }
    }    
}
void postOrder3(node *root)     //非递归后序遍历
{
    stack<node*> s;
    node *cur;                      //当前结点 
    node *pre=NULL;                 //前一次访问的结点 
    s.push(root);
    while(!s.empty())
    {
        cur=s.top();
        if((cur->lchild==NULL&&cur->rchild==NULL)||
           (pre!=NULL&&(pre==cur->lchild||pre==cur->rchild)))
        {
            cout<<cur->data<<" ";  //如果当前结点没有孩子结点或者孩子节点都已被访问过 
              s.pop();
            pre=cur; 
        }
        else
        {
            if(cur->rchild!=NULL)
                s.push(cur->rchild);
            if(cur->lchild!=NULL)    
                s.push(cur->lchild);
        }
    }    
}

/*一定要记住直接输入1 2 3 0 0 0 0 建立的是 左二叉树 平衡的应该是 1 2 0 0 3 0 0*/
int main()
{
	node *root;//=(node*)malloc(sizeof(node));//这里不要初始化了 因为建立的时候要初始化 
	printf("             Please select what you  want do\n");
	printf("----------------------------------------------\n");
	printf("    1.前序创建二叉树\n");
	printf("    2.递归前序遍历二叉树\n");
	printf("    3.递归中序遍历二叉树\n");
	printf("    4.递归后序遍历二叉树\n");
	printf("    5.求叶节点个数\n");
	printf("    6.求树的高度\n");
	printf("    7.求二叉树节点个数\n");
	printf("    8.交换左右子树\n");
	printf("    9.查找有无某个节点\n");
	printf("    10.非递归前序遍历二叉树\n");
	printf("    11.非递归前序遍历二叉树\n");
	printf("    12.非递归前序遍历二叉树\n");
	printf("    15.退出\n");
	 
	int i;
	
	while(true)
	{
		scanf("%d",&i);
     	switch(i)
	    {
	    	case 1: root=createTree();
			        printf("create tree is finished please select what you want do next:\n");break;
	    	case 2:	printf("Now outPut data in PreOrder:\n");
	                preOrder(root);
	                printf("output is over please select again\n");break;
	    	case 3: printf("Now outPut data in inOrder:\n");
	                inOrder(root);
					printf("output is over please select again\n");break;
	    	case 4: printf("Now outPut data in postOrder:\n");
	                postOrder(root);
					printf("output is over please select again\n");break;
	    	case 5: count=0;
	    	        CountLeaves(root);
                    printf("The leaves's count is:%d\n",count);
					printf("output is over please select again\n");break;//叶子节点的个数 
	    	case 6: int deep=deepLength(root);
                    printf("The tree's deepLength is:%d\n",deep);
					printf("output is over please select again\n");break;
	    	case 7: count=0;
	    	        CountNodes(root);
                    printf("The leaves's count is:%d\n",count);
					printf("output is over\n"); 
			        break;//求二叉树节点个数 
	    	case 8: exchange(root);
			        break;
            case 9: printf("please input what you want search\n");
                    int x;
                    scanf("%d",&x);
                    count=0;
                    search(root,x);
					if(count!=0)
                       {
					      printf("The tree has this root\n");
                          printf("output is over please select again\n");
                       }
                    else
                       {
					      printf("The tree not has this root\n");
					      printf("output is over please select again\n");
                       }
			        break;
            case 10:	printf("Now outPut data in PreOrder:\n");
	                preOrder2(root);
	                printf("output is over please select again\n");break;
            case 11:	printf("Now outPut data in PreOrder:\n");
	                inOrder2(root);
	                printf("output is over please select again\n");break;
            case 12:	printf("Now outPut data in PreOrder:\n");
	                postOrder3(root);
	                printf("output is over please select again\n");break;
	                
	    	case 15: exit(0); break;//包含在stdlib.h当中 
		
        }   
	} 
	
	return 0;
}



 
 

你可能感兴趣的:(tree,null,search,input,Exchange,output)