遍历树
来源:互联网 发布:java ffmpeg 视频转码 编辑:程序博客网 时间:2024/06/17 07:44
如何用栈实现递归与非递归的转换(一)三种遍历树的算法
一.为什么要学习递归与非递归的转换的实现方法?
1)并不是每一门语言都支持递归的.
2)有助于理解递归的本质.
3)有助于理解栈,树等数据结构.
二.三种遍历树的递归和非递归算法
递归与非递归的转换基于以下的原理:所有的递归程序都可以用树结构表示出来.需要说明的是,这个"原理"并没有经过严格的数学证明,只是我的一个猜想,不过在至少在我遇到的例子中是适用的.学习过树结构的人都知道,有三种方法可以遍历树:前序,中序,后序.理解这三种遍历方式的递归和非递归的表达方式是能够正确实现转换的关键之处,所以我们先来谈谈这个.需要说明的是,这里以特殊的二叉树来说明,不过大多数情况下二叉树已经够用,而且理解了二叉树的遍历,其它的树遍历方式就不难。
了.
1)前序遍历
a)递归方式:
void preorder_recursive(Bitree T) /* 先序遍历二叉树的递归算法 */
{
if (T) {
visit(T); /* 访问当前结点 */
preorder_recursive(T->lchild); /* 访问左子树 */
preorder_recursive(T->rchild); /* 访问右子树 */
}
}
b)非递归方式
void preorder_nonrecursive(Bitree T) /* 先序遍历二叉树的非递归算法 */
{
initstack(S);
push(S,T); /* 根指针进栈 */
while(!stackempty(S)) {
while(gettop(S,p)&&p) { /* 向左走到尽头 */
visit(p); /* 每向前走一步都访问当前结点 */
push(S,p->lchild);
}
pop(S,p);
if(!stackempty(S)) { /* 向右走一步 */
pop(S,p);
push(S,p->rchild);
}
}
}
2)中序遍历
a)递归方式
void inorder_recursive(Bitree T) /* 中序遍历二叉树的递归算法 */
{
if (T) {
inorder_recursive(T->lchild); /* 访问左子树 */
visit(T); /* 访问当前结点 */
inorder_recursive(T->rchild); /* 访问右子树 */
}
}
b)非递归方式
void inorder_nonrecursive(Bitree T)
{
initstack(S); /* 初始化栈 */
push(S, T); /* 根指针入栈 */
while (!stackempty(S)) {
while (gettop(S, p) && p) /* 向左走到尽头 */
push(S, p->lchild);
pop(S, p); /* 空指针退栈 */
if (!stackempty(S)) {
pop(S, p);
visit(p); /* 访问当前结点 */
push(S, p->rchild); /* 向右走一步 */
}
}
}
3)后序遍历
a)递归方式
void postorder_recursive(Bitree T) /* 中序遍历二叉树的递归算法 */
{
if (T) {
postorder_recursive(T->lchild); /* 访问左子树 */
postorder_recursive(T->rchild); /* 访问右子树 */
visit(T); /* 访问当前结点 */
}
}
b)非递归方式
typedef struct {
BTNode* ptr;
enum {0,1,2} mark;
} PMType; /* 有mark域的结点指针类型 */
void postorder_nonrecursive(BiTree T) /*
后续遍历二叉树的非递归算法 */
{
PMType a;
initstack(S); /* S的元素为PMType类型 */
push (S,{T,0}); /* 根结点入栈 */
while(!stackempty(S)) {
pop(S,a);
switch(a.mark)
{
case 0:
push(S,{a.ptr,1}); /* 修改mark域 */
if(a.ptr->lchild)
push(S,{a.ptr->lchild,0}); /* 访问左子树 */
break;
case 1:
push(S,{a.ptr,2}); /* 修改mark域 */
if(a.ptr->rchild)
push(S,{a.ptr->rchild,0}); /* 访问右子树 */
break;
case 2:
visit(a.ptr); /* 访问结点 */
}
}
}
- 树-遍历
- 遍历树
- 二叉树遍历、分层遍历
- 二叉树遍历,深度有限遍历,广度优先遍历,前序中序后续优先遍历,层次遍历
- 树遍历方式总结:层次遍历、先序遍历、中序遍历、后序遍历
- 遍历节点树、遍历元素树、遍历API、查找 API
- 二叉树的遍历(层遍历和深度遍历)
- java遍历树(深度遍历和广度遍历)
- 二叉树的前序中序后序遍历,非递归遍历 层次遍历
- 树 前序遍历,中序遍历,后序遍历
- 二叉树的先中后序遍历,递归遍历,非递归遍历
- 二叉树,前中后遍历,层遍历
- 二叉树层次遍历和深度遍历
- 树遍历之推广到图遍历
- 二叉树遍历 层序遍历
- 二叉树遍历-----前序后序迭代遍历的新思路
- 二叉树层次遍历和深度遍历
- 数据结构二叉树遍历之中序遍历
- DNS FAILOVER SETTING
- 谨慎使用String作为HashMap的Key
- UVA10413 Crazy Savages 扩展欧几里德的应用
- android计算器
- 学习心得
- 遍历树
- 增加Linux虚拟机linux硬盘容量
- AVL树(平衡二叉树)
- Android 虚拟键盘弹出把底部栏顶上去的解决办法
- 归并排序
- 表单基础
- linux 下新建目录自动加锁的解决办法
- C++之从头开始(6)String 剔除 空格
- 1.3.2:编写简单的jQuery代码