zoukankan      html  css  js  c++  java
  • 递归和非递归实现二叉树的遍历

    #include <stdlib.h>
    #include<stack>
    #include<string.h>
    #include<iostream>
    using namespace std;
    typedef struct Node{//ABDG##H###CE#I##F##
    	Node* left;
    	Node* right;
    	char data;
    }Node,*PNode;
    
    void create(PNode &T){
    	char c;
    	scanf("%c",&c);
    	if(c=='#') T=NULL;
    	else{
    		T=(PNode)malloc(sizeof(Node));//不要忘了申请地址
    		T->data=c;
    		create(T->left);
    		create(T->right);
    	}
    	
    }
    void pre1(PNode &T){
    	if(T) cout<<T->data<<" ";
    	if(T->left!=NULL) pre1(T->left);
    	if(T->right!=NULL) pre1(T->right); 
    }
    void pre2(PNode &T){
    	if(T==NULL) return;
    	stack<PNode>s;
    	PNode p=T;
    	while(!s.empty()||p){
    		while(p){
    			cout<<p->data<<" ";
    			s.push(p);
    			p=p->left; 
    		}
    		if(!s.empty()){
    			p=s.top();
    			s.pop();
    			p=p->right;
    		}
    	}
    }
    void In1(PNode &T){
    	if(T==NULL) return;
    	if(T->left!=NULL) In1(T->left);
    	cout<<T->data<<" ";
    	if(T->right!=NULL) In1(T->right);
    }
    void In2(PNode &T){
    	if(T==NULL) return;
    	PNode p=T;
    	stack<PNode>s;
    	while(p||!s.empty()){
    		while(p){
    			s.push(p);
    			p=p->left;
    		}
    		if(!s.empty()){
    			p=s.top();
    			s.pop();
    			cout<<p->data<<" ";
    			p=p->right;
    		}
    	}
    }
    void Post1(PNode &T){
    	if(T==NULL) return;
    	if(T->left!=NULL) Post1(T->left);
    	if(T->right!=NULL) Post1(T->right);
    	cout<<T->data<<" ";
    }
    void Post2(PNode &T){
    	stack<PNode>s;
    	PNode p=T,r=NULL;
    	while(p||!s.empty()){
    		if(p){
    			s.push(p);
    			p=p->left;
    		}else{
    			p=s.top();
    			if(p->right&&p->right!=r){
    				p=p->right;
    				s.push(p);
    				p=p->left;
    			}else{
    				s.pop();
    				cout<<p->data<<" ";
    				r=p;
    				p=NULL;
    			}
    		}
    	}
    } 
    void Post22(PNode &T){
    	 if (T == NULL)
            return;
        stack<PNode> s;
        //pCur:当前访问节点,pLastVisit:上次访问节点
        PNode pCur, pLastVisit;
    
        pCur = T;
        pLastVisit = NULL;
        //先把pCur移动到左子树最下边
        while (pCur)
        {
            s.push(pCur);
            pCur = pCur->left;
        }
        while (!s.empty())
        {
            //走到这里,pCur都是空,并已经遍历到左子树底端(看成扩充二叉树,则空,亦是某棵树的左孩子)
            pCur = s.top();
            s.pop();
            //一个根节点被访问的前提是:无右子树或右子树已被访问过
            if (pCur->right == NULL || pCur->right == pLastVisit)
            {
                cout <<pCur->data<<" ";
                //修改最近被访问的节点
                pLastVisit = pCur;
            }
            /*这里的else语句可换成带条件的else if:
            else if (pCur->lchild == pLastVisit)//若左子树刚被访问过,则需先进入右子树(根节点需再次入栈)
            因为:上面的条件没通过就一定是下面的条件满足。仔细想想!
            */
            else
            {
                //根节点再次入栈
                s.push(pCur);
                //进入右子树,且可肯定右子树一定不为空
                pCur = pCur->right;
                while (pCur)
                {
                    s.push(pCur);
                    pCur = pCur->left;
                }
            }
        }
        cout << endl;
    }
    int main(){
    	PNode T; 
    //	T=(PNode) malloc(sizeof(Node));
    	create(T);
    	printf("递归前序遍历
    ");
    	pre1(T);
    	cout<<"
    非递归前序遍历"<<endl;
    	pre2(T); 
    	cout<<"
    递归中序遍历
    ";
    	In1(T);
    	cout<<"
    非递归中序遍历
    ";
    	In2(T); 
    	cout<<"
    递归后序遍历
    ";
    	Post1(T);
    	cout<<"
    非递归后序遍历
    ";
    	Post2(T); 
    	return 0;
    } 
    
    
    ////https://blog.csdn.net/z_ryan/article/details/80854233
    //#include<iostream>
    //#include <stdlib.h>
    //#include<stack>
    //#include<string.h>
    //using namespace std;
    //typedef struct TreeNode{
    //	TreeNode *left,*right;
    //	char c;
    //}TreeNode,*pNode;
    //void create(pNode &T){
    //	char h;
    //	scanf("%c",&h);
    //	if(h=='#')
    //	T=NULL;
    //	else{
    //		T=(pNode)malloc (sizeof(TreeNode));
    //		T->c=h;
    //		create(T->left);
    //		create(T->right); 
    //	}
    //}
    //void pre1(pNode &T){
    //	
    //	printf("%c ",T->c);
    //	if(T->left!=NULL) pre1(T->left);
    //	if(T->right!=NULL) pre1(T->right);
    //}
    //void pre2(pNode &T){
    //	stack<pNode>s;
    //	printf("
    非递归前序"); 
    //	if(T!=NULL)
    //		s.push(T);
    //	while(!s.empty()){
    //		pNode p=s.top();
    //		s.pop();
    //		printf("%c ",p->c);	
    //	if(p->right!=NULL)	s.push(p->right);
    //	if(p->left!=NULL)	s.push(p->left);
    //	}
    //	
    //}
    //void In1(pNode &T){
    //	
    //	if(T->left!=NULL) In1(T->left);
    //	printf("%c ",T->c);
    //	if(T->right!=NULL) In1(T->right);
    //}
    //void In2(pNode &T){
    //	stack<pNode>s;
    //	printf("
    非递归中序");
    //	pNode p=T;
    //	while(p!=NULL||!s.empty()){
    //		if(p!=NULL){
    //			s.push(p);
    //			p=p->left;
    //		}else{
    //			p=s.top();
    //			s.pop();
    //			printf("%c ",p->c);
    //			p=p->right;
    //		}
    //	}
    //}
    //void Tail1(pNode &T){	
    //	if(T->left!=NULL) Tail1(T->left);
    //	if(T->right!=NULL) Tail1(T->right);
    //	printf("%c ",T->c);
    //}
    //int main(){
    //	TreeNode *T;//ABDG##H###CE#I##F##
    //	 T=(pNode)malloc(sizeof(TreeNode));
    //	 create(T);
    //	 printf("递归前序");
    //	 pre1(T);
    //	 pre2(T);
    //	 printf("
    递归中序");
    //	 In1(T); 
    //	 In2(T);
    //	  printf("
    递归后序");
    //	 Tail1(T); 
    //	return 0;
    //} 
    

      

  • 相关阅读:
    vue项目引用less报错
    vue dev配置代理会报404
    为什么需要用到消息队列
    理解kafka消费者
    WebSocket和long poll、ajax轮询的区别
    数据库开发——MySQL——慢查询优化
    数据库开发——MySQL——索引原理
    数据库开发——MySQL——函数与流程控制
    数据库开发——MySQL——内置功能
    数据库开发——MySQL——pymysql模块
  • 原文地址:https://www.cnblogs.com/tao7/p/10163600.html
Copyright © 2011-2022 走看看