二叉树的遍历PPT 课件

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
}
7.4.3 二叉树遍历的非递归实现
第5章介绍了由递归程序转换成非递归程序的两种方法: 简单递归程序的转换和复杂递归程序的转换;
二叉树的遍历问题应该属于后者,即在采用非递归方式 实现二叉树遍历时,必须使用一个堆栈记录回溯点,以 便将来进行回溯。以下为一个顺序栈的定义及其部分操 作的实现。
typedef struct stack
最后访问根结点。
a
b
c
前序遍历:abdefgc
d
f
中序遍历: debgfac
后序遍历: edgfbca
eg
练习!!!!!!!!
练习!!!!!!!!
A
B
C
前序序列: ABDGCEFH 中序序列: DGBAECHF 后序序列: GDBEHFCA
D G
E
F
H
图 5-15
下面我们再给出一种遍历二叉树的方法
{ s->data[++s->top]=t;
}Βιβλιοθήκη Baidu
bintree pop(seqstack *s) /*出栈*/
{ if (s->top!=-1) { s->top--; return(s->data[s->top+1]); } else return NULL; }
1、 二叉树前序遍历的非递归实现
(1)二叉树的前序遍历 首先访问根结点; 然后按照前序遍历的顺序访问根结点的左子树; 再按照前序遍历的顺序访问根结点的右子树。
(2)二叉树的中序遍历 首先按照中序遍历的顺序访问根结点的左子树;
然后访问根结点; 最后按照中序遍历的顺序访问根结点的右子树。
(3)二叉树的后序遍历 首先按照后序遍历的顺序访问根结点的左子树; 然后按照后序遍历的顺序访问根结点的右子树;
}
遍历二叉树递归算法
2 、中序遍历二叉树的递归算法 void inorder(bintree t) { if (t) { inorder(t->lchild); printf(“%c”,t->data); inorder(t->rchild); } }
3 、后序遍历二叉树的递归算法 void postorder(bintree t) { if (t) { postorder(t->lchild); postorder(t->rchild); printf("%c",t->data); } }
7.4 二叉树的遍历
7.4.1 二叉树遍历的定义
所谓二叉树的遍历,是指按一定的顺序对二叉 树中的每个结点均访问一次,且仅访问一次。
按照根结点访问位置的不同,通常把二叉树的 遍历分为六种:
TLR(根左右), TRL(根右左) LTR(左根右), RTL(右根左) LRT(左右根), RLT(右左根)
其中,TRL、RTL和RLT三种顺序在左右子树之间均 是先右子树后左子树,这与人们先左后右的习惯不 同,因此,往往不予采用。余下的三种顺序TLR、 LTR和LRT根据根访问的位置不同分别被称为前序遍 历、中序遍历和后序遍历。
前序遍历一棵非空二叉树t 时,访问完t的根结点后, 就应该进入t的左子树,但此时必须将t保存起来, 以便访问完其左子树后,通过t的RCHILD再进入其 右子树的访问,即在t处必须设置一个回溯点;对t 的左子树和右子树的遍历也是如此。仔细观察不难 发现,这些回溯点应该使用栈来进行管理。在整个 二叉树前序遍历的过程中,程序要做的工作始终分 成两个部分:当前正在处理的树(子树)和保存在 栈中待处理的部分,只有这两部分的工作均完成后, 程序方能结束。
(1)对一棵二叉树中序遍历时,若我们将二叉树严
格地按左子树的所有结点位于根结点的左侧,右子树的所
有结点位于根右侧的形式绘制,就可以对每个结点做一条
垂线,映射到下面的水平线上,由此得到的顺序就是该二
叉树的中序遍历序列。
B D
G
A
C
E
F
H
D G B AE
图 5-16
CH F
7.4.2 二叉树遍历的递归实现
非递归实现二叉树的前序遍历
void preorder1(bintree t) /*非递归实现二叉树的前序遍历*/ { seqstack s; s.top=-1; while ((t) || (s.top!=-1)) /*当前处理的子树不为空或栈不为空则循环*/ { while (t) { printf("%c ",t->data); s.top++; s.data[s.top]=t; t=t->lchild; } if (s.top>-1) { t=pop(&s); t=t->rchild; } }
由于二叉树的遍历是递归定义的,因此采用递 归方式实现二叉树遍历的算法十分方便,只要按 照各种遍历规定的次序,访问根结点时就输出根结点 的值,访问左子树和右子树时进行递归调用即可。
1 、前序遍历二叉树的递归算法 void preorder(bintree t)
{ if (t) { printf("%c",t->data); preorder(t->lchild); preorder(t->rchild); }
/*栈结构定义*/
{ bintree data[100];
int tag[100];//为栈中每个元素设置的标记,用于后序遍历 int top; //栈顶指针,指向栈顶元素,这和2章中top有区别
} seqstack;
void push(seqstack *s,bintree t) /*进栈*/
void createbintree(bintree *t) { char ch; if ((ch=getchar())==' ') *t=NULL; else { *t=(bintnode *)malloc(sizeof(bintnode)); /*生成二叉树的根结点*/ (*t)->data=ch; createbintree(&(*t)->lchild); /*递归实现左子树的建立*/ createbintree(&(*t)->rchild); /*递归实现右子树的建立*/ }
4 、二叉树的创建算法
利用二叉树前序遍历的结果可以非常方便地生成给定的
二叉树,具体做法是:将第一个输入的结点作为二叉树的 根结点,后继输入的结点序列是二叉树左子树前序遍历的 结果,由它们生成二叉树的左子树;再接下来输入的结点 序列为二叉树右子树前序遍历的结果,应该由它们生成二 叉树的右子树;而由二叉树左子树前序遍历的结果生成二 叉树的左子树和由二叉树右子树前序遍历的结果生成二叉 树的右子树的过程均与由整棵二叉树的前序遍历结果生成 该二叉树的过程完全相同,只是所处理的对象范围不同, 于是完全可以使用递归方式加以实现。
相关文档
最新文档