先序遍历
来源:互联网 发布:115会员 淘宝 编辑:程序博客网 时间:2024/05/17 00:02
二叉树不是线性结构,因此没有全局的顺序。而遍历算法将在一个局部给二叉树添加一个次序,从而间接地定义出全局的顺序。
先序遍历
考察一个二叉树的局部的一个节点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
- Morris 先序遍历
- 数据结构---先序遍历
- 数据结构---先序遍历
- 先序遍历
- 先序遍历二叉树
- 先序遍历二叉树
- 二叉树 - 先序遍历
- 先序遍历二叉树
- 先序遍历二叉树
- 树的先序遍历
- 树的先序遍历
- 先序遍历 中序遍历 后序遍历
- 先序遍历和中序遍历求后序遍历
- 已知先序遍历和中序遍历求后序遍历
- 已知先序遍历和中续遍历求后序遍历
- 二叉树的先序建立及先序遍历:
- 先序,中序,后序遍历
- 先序,中序,后序遍历
- 数据库备份和恢复以及表数据的导入和导出
- SparkR终极解决方案
- 字符串转换成整数-微软面试题
- Django项目配置让其他用户电脑访问Project
- (4)linux进程通讯之共享内存
- 先序遍历
- 练习24
- 解决 This application requires Java Runtime Environment X
- CentOS6.5final下TFS的安装和使用
- Linux系统的下载和安装
- hadoop序列化和反序列化
- 生产者和消费者
- ansible命令
- Linux命令的基本格式