zoukankan      html  css  js  c++  java
  • 二叉树的三种遍历,递归与非递归

    1.先序遍历
    #include "stdafx.h"
    #include<iostream>
    using namespace std;
    typedef struct BTreeNode
    {
    	int data;
    	struct BTreeNode *lchild,*rchild;
    }BTree;
    int _tmain(int argc, _TCHAR* argv[])
    {
    	return 0;
    }
    void PreOrder(BTree *b)
    {       
    	if(b!=NULL)
    	{
    		printf("%c ",b->data);
    		PreOrder(b->lchild);
    		PreOrder(b->rchild);
    	}
    }
    

     2.中序遍历

    void InOrder(BTree *b)
    {
    	if(b!=NULL)
    	{
    		InOrder(b->lchild);
    		printf("%c ",b->data);
    		InOrder(b->rchild);
    	}
    }
    

      3.后序遍历

    void PostOrder(BTree *b)
    {
    	if(b!=NULL)
    	{
    		PostOrder(b->lchild);
    		PostOrder(b->rchild);
    		printf("%c ",b->data);
    	}
    }
    

     4.使用栈的非递归遍历

    非递归实现

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

         对于任一结点P:

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

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

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

    void preOrder2(BinTree *root)     //非递归前序遍历 
    {
        stack<BinTree*> s;
        BinTree *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;
            }
        }
    } 
    

     5.使用栈的中序

    void inOrder2(BinTree *root)      //非递归中序遍历
    {
        stack<BinTree*> s;
        BinTree *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;
            }
        }    
    }
    

     6.后序非递归

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

    void postOrder3(BinTree *root)     //非递归后序遍历
    {
        stack<BinTree*> s;
        BinTree *cur;                      //当前结点 
        BinTree *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 "stdafx.h"
    #include<iostream>
    using namespace std;
    typedef struct BTreeNode
    {
    	int data;
    	struct BTreeNode *lchild,*rchild;
    }BTree;
    typedef struct stacknode
    {
    	BTree *node;
    	int tag;//tag为0表示结点左子女已经访问,为1表示右子女已经访问
    }stack;
    int _tmain(int argc, _TCHAR* argv[])
    {
    	return 0;
    }
    void PostOrder2(BTree *b)
    {
    	stack s[100];
    	int top=-1;
    	stack temp;//暂存结点信息
    	while(b||top>-1)
    	{
    		while(b)
    		{
    			temp.node=b;
    			temp.tag=0;//左结点已访问
    			s[++top]=temp;
    			b=b->lchild;
    		}
    		while(top&&s[top].tag==1){ //表示右子树访问完毕,所以访问根节点, 此处是while不是if  
    			//b = s[top --].node;
    			//cout << b->val << ' ';
    			/*之前是写这两行,但是会导致最后top为0时,p非空,所以会不断循环最外层的while(p||top)
    			如果要写这两行而不写下面那句的话,要采用do{}while(top);*/
    			cout << s[top --].node->data<< ' ';
    		}
    		if(top!=-1)
    		{
    			s[top].tag= 1; //右结点已访问           
    			b = s[top].node;           
    			b = b->rchild;
    		}
    	}
    }
    
  • 相关阅读:
    Building a flexiable renderer
    Indirect Illumination in mental ray
    我的心情
    Cellular Automata
    Subsurface Scattering in mental ray
    Shader Types in mental ray
    BSP Traversal
    我的渲染器终于达到了MR的速度
    How to handle displacement and motion blur
    说明
  • 原文地址:https://www.cnblogs.com/tgkx1054/p/2628127.html
Copyright © 2011-2022 走看看