先序遍历

二叉树不是线性结构,因此没有全局的顺序。而遍历算法将在一个局部给二叉树添加一个次序,从而间接地定义出全局的顺序。

先序遍历

考察一个二叉树的局部的一个节点v,则v的左子树与右子树(假设它们都存在)规定一个次序,先序遍历下,先访问节点v,然后深入左子树,再深入右子树。根据上述定义,实现递归版的先序遍历算法十分简单。
template<typename T,typename VST>void travPre_R(BinNodePosi(T) v,VST& visit){
    if(!v) return;
    visit(v->data);
    travPre_R(v->lc,visit);
    travPre_R(v->rc,visit);
}

而深入讨论该算法,该算法属于尾递归,采用消除尾递归的形式可以节省常系数意义上的时间复杂度和空间复杂度,当然,迭代版的先序遍历算法在总体意义上还是需要线性时间正比树高。

迭代思路:从整个算法来看,就是先访问当前节点,然后转入左子树,再转到右子树。可以不以引入一个栈结构,将遇到的所有节点压入栈,左子树优先出栈所以要后入栈。

template<typename T,typename VST>void travPre_R1(BinNodePosi(T) v,VST& visit){
    Stack<BinNodePosi(T)> S;
    if(v) S.push(v);//遇到节点全部压入栈
    while(!S.empty()){//栈不空
        v = S.pop(); //依次弹出
        visit(v->data);
        if(HasRChild(*v)) S.push(v->rc);//右子树优先
        if(HasLChild(*v)) S.push(v->lc);//左子树次之
    }
}

这是尾递归消除,因此不适用于一般的情况。

重新换一种角度来审视先序遍历,可不可以认为是这种情况,总是先访问所有的左子树,然后才开始访问右子树。
也就是说:
  • 自上而下遍历所有左子树。
  • 自下而上对所有右子树进行访问。
template<typename T,typename VST>void travPre_R2(BinNodePosi(T) v,VST& visit){
    Stack<BinNodePosi(T)> S;
    while(1){
        visitAlongLeftBranch(x,visit,S);
        if(S.empty()) break;
        x = S.pop();
    }
}
template<typename T,typename VST>void visitAlongLeftBranch(BinNodePosi(T) x,VST& visit, Stack<BinNodePosi(T)> &S){
    while(x){
        visit(x->data);
        S.push(x->rc);
        x = x->lc;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值