5.5 遍历二叉树和线索二叉树

5.5.1 遍历二叉树

遍历定义顺着某一条搜索路径巡防二叉树中的结点,使得每个节点均被访问一次,而且仅被访问一次(又称周游)
遍历目的:得到树中所有结点的一个线性排列。
遍历用途:它是树结构插入、删除、修改、查找和排序运算的前提,是二叉树一切运算的基础和核心。

1.遍历二叉树的算法描述

1.1遍历方法

L:遍历左子树
D:访问根结点
R:遍历右子树
共有六种:DLR,LDR,LRD,DRL,RDL,RLD
规定先左后右则有三种:

  1. DLR—先(根)序遍历 的操作定义
    若二叉树为空,则空操作,否则:
    (1)访问根节点;
    (2)先序遍历左子树;
    (2)先序遍历右子树。
  2. LDR—中(根)序遍历 的操作定义
    若二叉树为空,则空操作;否则:
    (1)中序遍历左子树;
    (2)访问根结点;
    (3)中序遍历右子树。
  3. LRD—后(根)序遍历 的操作定义
    若二叉树为空,则空操作;否则:
    (1)后序遍历左子树;
    (2)后序遍历右子树;
    (3)访问根结点。

例题——二叉树表示算术表达式
写出下图a所示二叉树的先序、中序和后序遍历顺序
图a
遍历结果:
先序:-+axb-cd/ef(表达式的前缀表示—波兰式)
中序:a+bxc-d-e/f(表达式的中缀表示
后序:abcd-x+ef/-(表达式的后缀表示—逆波兰式)

2.根据遍历序列确定二叉树

2.1若二叉树中各结点的值均不相同,则二叉树结点的先序序列、中序序列和后序序列都是唯一的
2.2由二叉树的先序序列和中序序列,或由二叉树的后序序列和中序序列可以唯一确定一棵二叉树

3.二叉树遍历的算法实现(递归)

3.1先序遍历

若二叉树为空,则空操作;
若二叉树非空,
访问根结点(D)
前序遍历左子树(L)
前序遍历右子树(R)

先序遍历算法

伪代码:

Status PreOrderTraverse(BiTree T){
if(T==NULL) return OK;//空二叉树
else{
visit(T);//访问根结点
PreOrderTraverse(T->lchild);//递归遍历左子树
PreOrderTraverse(T->rchild);//递归遍历右子树

代码:

void Pre(BiTree *T){
if(T!=NULL){
printf("%d\t",T->data);
pre(T->lchild);
pre(T->rchild);
}}
3.2中序遍历

若二叉树为空,则空操作
否则:
中序遍历左子树(L);
访问根结点(D)
中序遍历右子树®

伪代码:

Status InOrderTraverse(BiTree T){
if(T=NULL) return OK;//空二叉树
else{
InOrderTRaverse(T->lchild);//递归遍历左子树
visit(T);//访问根结点;
InOrderTraverse(T->rchild);//递归遍历右子树
}

代码:

Status InOrderTraverse(BiTree T){
if(T==NULL) return OK;
else{
InOrderTraverse(T->lchild);
cout<<T->data;
InordeerTraverse(T->rchild);
}
}
3.3后序遍历

若二叉树为空,则空操作
否则
后序遍历左子树(L)
后序遍历右子树®
访问根结点(D)

伪代码:

Status PostOrderTraverse(BiTree T){
if(T==NULL) return OK;//空二叉树
else{
PostOrderTraverse(T->lchild);//递归遍历左子树
PostOrderTraverse(T->rchild);//递归遍历右子树
visit(T);//访问根结点
}

代码:

Status PostOrderTraverse(BiTree T){
if(T==NULL) return Ok;
else{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout<<T->data;
}
}
3.4 遍历算法的分析
!!!快速得出访问二叉树序列的方法

遍历算法的分析:

如果去掉算法代码中的输出语句,从递归的角度看,三种算法是完全相同的,或说这三种算法的放翁路径是相同的,只是访问结点的时机不同.
从虚线的出发点到终点的路径上,每个结点经过3次.

第一次经过时访问=先序遍历
第二次经过时访问=中序遍历
第三次经过时访问=后序遍历
在这里插入图片描述

效率

时间效率:O(n)//每个结点只访问一次
空间效率:O(n)//栈占用的最大辅助空间

4.遍历二叉树的非递归算法

中序遍历 非递归 算法
二叉树中序遍历的非递归算法的关键:在中序遍历过某结点的整个左子树后,如何找到该结点的根以及右子树。
基本思想:
(1)建立一个栈
(2)根结点进栈,遍历左子树
(3)根结点出栈,输出根结点,遍历右子树
代码

Status InOrderTraverse(BiTree T){
BiTree p;//表示根结点
InitStack(S);//建立一个栈
p=T;//讲当前根结点初始化为二叉树的根
while(p||!StackEmpty(S)){//当p不为或者栈不为空
if(p){//如果p不为空
     push(S,p);//将p存入栈
     p=p->lchild;//p指向p的左孩子
}
else{
     pop(S,q);//p为空,也就是上一个p的左孩子为空
     printf("%c",q->data);//说明当前子树走到了最底层,输出栈顶的元素的data域值
     p=q->rchild;//p指向栈顶q的右孩子
}
     return Ok;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值