二叉树分层遍历(递归以及非递归的实现)
来源:互联网 发布:淘宝的等级划分 编辑:程序博客网 时间:2024/04/30 02:14
树的遍历是比较基本的数据结构操作方法,中序遍历、线序遍历和后续遍历什么的基本上递归一下,三行代码就能搞定。但是,树的按层遍历就会稍微复杂一些。
既然是使用了栈的思想,那么,按层遍历树是否能用递归实现呢?能够使用递归的一个先决条件是当前的问题能够拆分成为子问题。
主要思想是使用栈暂存数据,一个栈用于保存当前层的节点,另外一个栈用于保存下一层的节点,在遍历该层时,将下一层的所有节点都存储到栈中,在下一次遍历中使用。
思路比较清楚,贴下这种思路的代码。
void printTreeLevel(Node *node){ vector<Node*> save[2]; save[0].push_back(node); int cnt = 0; while (save[cnt%2].size()) { vector<Node*>::iterator it = save[cnt%2].begin(); vector<Node*>::iterator end= save[cnt%2].end(); for (;it != end;++it) { cout<<(*it)->expr<<" "; if ((*it)->left) { save[(cnt+1)%2].push_back((*it)->left); } if ((*it)->right) { save[(cnt+1)%2].push_back((*it)->right); } } cout<<endl; save[cnt%2].clear(); ++cnt; } return;}
既然是使用了栈的思想,那么,按层遍历树是否能用递归实现呢?能够使用递归的一个先决条件是当前的问题能够拆分成为子问题。
对于这个问题,一个直观的想法是这样,例如如下的一棵树 (a& b)|(c|d)&((e&f)&f|(g&i)):
一个直观的想法是这样:
- 找到最深的一个节点,遍历该节点及其兄弟节点
- 如果其父亲不为空,递归其父亲节点
- 如果为空,结束遍历
当然,按照上述方法进行遍历得到的是一颗倒着的树,但是如果把该过程反过来,那么会存在不知道哪条路径最长的问题。
但是如果将问题再简化一点,只输出指定层的节点,那么问题就被简化了很多。
因此问题被分解为:
- 获取树的深度d
- 调用d次输出函数
void printTreeLevelDG(Node *node, int nLevel) { if (!node || nLevel<1) { return; } if (nLevel == 1) { cout<<node->expr<<"\t"; } printTreeLevelDG(node->left, nLevel-1); printTreeLevelDG(node->right,nLevel-1);}//调用点 for (int i = 1;i<nDepth;++i) { printTreeLevelDG(stackExpr.top(), i); cout<<endl; }
- 二叉树分层遍历(递归以及非递归的实现)
- 二叉树的遍历(递归实现+非递归实现)
- 二叉树的遍历(递归,非递归)实现
- 二叉树的遍历(非递归和递归实现)
- 二叉树的非递归遍历以及递归遍历
- 二叉树的递归遍历以及非递归遍历
- 二叉树的创建,递归遍历以及非递归遍历
- 二叉树的链表实现以及非递归遍历
- 二叉树三种遍历(递归以及非递归实现)
- 二叉树的先序递归以及非递归遍历
- 二叉树的递归,层次,以及非递归遍历
- 二叉树的遍历 递归以及非递归
- 非递归实现二叉树的遍历
- 非递归实现二叉树的遍历
- 二叉树遍历的非递归实现
- 二叉树遍历的非递归实现
- 二叉树遍历的非递归实现
- 二叉树的非递归遍历实现
- CAN总线的仲裁机制
- PPPOE
- 使用AutoIt做广东省英语A级与计算机水平考试的考前测试之第2版
- MySQL自带的性能压力测试工具mysqlslap详解
- 基础语法
- 二叉树分层遍历(递归以及非递归的实现)
- apt
- Cocos2d-x中与属性相关的宏
- 雅虎的收购战略
- C++第16周项目4 -处理C++源代码 - (2)花括号单独占一行
- Java中serialVersionUID的解释
- 根据文件名中含有的scriptid更新数据库中的对应的Version字段
- OIT(Order-independent Transparent)顺序无关的透明
- 第十一次c语言上机实践操作