二叉树的非递归遍历

递归时间、空间效率低、这里使用栈改为非递归。

前序遍历:

1.根节点入栈,
2.栈顶元素出栈,访问
3.该元素的右儿子入栈
4.该元素的左二子入栈
重复234直到栈空

中序遍历

区分两种情况(图)
1.用原有的Node类构造一个带有入栈次数的StNode
2.根节点入栈
3.栈顶元素出栈,如果是第一次,自己入栈,左儿子入栈;如果是第二次,访问,右儿子入栈。
4.重复3直到栈空

中序遍历

和中序类似,区分三种情况
1.用原有的Node类构造一个带有入栈次数的StNode
2.根节点入栈
3.栈顶元素出栈,如果是第一次,自己入栈,左儿子入栈;如果是第二次,自己入栈,右儿子入栈。如果是第三次,访问。
4.重复3直到栈空
在这里插入图片描述

代码

构造StNode

 struct Node{//二叉树的结点类
        Node*left,*right;
        Type data;
        Node():left(NULL),right(NULL){}
        //参数化列表,内置结构体,结构体也可以有函数,不同之处:结构体定义中默认情况下的成员是public,而类定义中的默认情况下的成员是private的。
        Node(Type item,Node *L=NULL,Node *R=NULL):data(item),left(L),right(R){}
    };
struct StNode{
        Node*node;
        int TimesPop;
        StNode(Node*N=NULL):node(N),TimesPop(0){}//struct构造struct
    };

非递归遍历

    void preOrder(){
        stack<Node*>s;
        Node *current;
     
        cout<<"前序遍历:";
        s.push(root);
        while (!s.empty()) {
            current = s.top();
            s.pop();
            cout<<current->data;
            if (current->right!=NULL) {
                s.push(current->right);
            }
            if (current->left!=NULL) {
                s.push(current->left);
            }
        }
    }
    
    void midOrder(){
        stack<StNode>s;
        StNode current(root);
        cout<<"中序遍历:";
        s.push(current);
        while (!s.empty()) {
            current=s.top();
            s.pop();
            if(++current->TimesPop==1){
                s.push(current);
                if(current.node->left!=NULL)
                s.push(StNode(current.node->left));//这个神仙操作,先求node,再构造回去,绕一圈
        }
            else{
                cout<<current.node->data;
                if(current.node->right!=NULL)
                s.push(Stnode(current.node->right));
    }
        }
    }
    
    void postOrder()  {
        stack<StNode>s;
        StNode current(root);
        cout<<"后序遍历:";
        s.push(current);
        while (!s.empty()) {
            current=s.top();
            s.pop();
            if(++current->TimesPop==1){
                s.push(current);
                if(current.node->left!=NULL)
                    s.push(StNode(current.node->left));//这个神仙操作,先求node,再构造回去,绕一圈
            }
            else if(++current->TimesPop==2){
                s.push(current);
                if(current.node->right!=NULL)
                    s.push(StNode(current.node->right));//这个神仙操作,先求node,再构造回去,绕一圈
            }
            else cout<<current.node->data;
        }
        
    }
    

对比递归遍历

 void preOrder()const{
        if(root!=NULL){
            cout<<"\n先序遍历:";//\n加在”“里面也可以换行
            preOrder(root);
        }
    }
    void midOrder()const{
           if(root!=NULL){
               cout<<"\n中序遍历:";
               midOrder(root);
           }
       }
    void postOrder()const{
           if(root!=NULL){
               cout<<"\n后序遍历:";
               postOrder(root);
           }
       }

具体解释

1.前序遍历

在这里插入图片描述
2.中序遍历
在这里插入图片描述
3.后序遍历
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值