中序遍历和线索化二叉树(精)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

构造二叉链表
按下列次序输入字符: ABCDEGF (其中表示空格字符) 可建立如右图的二叉链表.
C E G A
B
D F
6.3.2 线索二叉树
遍 历ห้องสมุดไป่ตู้是 非 线 性 结 构 的 线 性 化 操 作 保留遍历过程的顺序信息 ---- 线索二叉树的表示: 若结点有左子树,则其LCHILD域指示其左孩子, 否则令LCHILD域指示其前驱; 若结点有右子树,则其RCHILD域指示其右孩子, 否则令RCHILD域指示其后继。
Status InOrderTraverse(BiTree T, Status(* Visit)(TElemType e)){ if (T){ if (InOrderTraverse(T->lchild,Visit)) if (Visit(T->data)) if (InOrderTraverse(T->rchild,Visit)) return OK; return ERROR; }else return OK; }//InOrderTraverse
0 14 0
Thrt
上例树的形态
B
1 2 3 4 5 6 7 8 9 10 11 12 13 14
Info LtagLchildRtag Rchild A 0 2 0 3 B 0 4 0 5 C 0 6 1 Thrt D 1 Thrt 1 2 E 0 7 0 8 F 1 1 0 9 G 0 10 0 11 H 1 5 1 1 I 0 12 1 3 J 0 13 1 7 K 1 7 0 14 L 1 6 1 9 M 1 2 1 10 N 1 11 1 5
中序遍历二叉树的非递归算法
Status InOrderTraverse(BiTree T, Status(* Visit) (TElemType e)){ 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); if (!Visite(p->data)) return ERROR; Push(S,p->rchild); } } return OK; }//InOrderTraverse

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

A B C D F G E

CFDBGEA
后序遍历二叉树的递归算法

Status PostOrderTraverse(BiTree T, Status(* Visit)(TElemType e)){ if (T){ if (PostOrderTraverse(T->lchild,Visit)) if (PostOrderTraverse(T->rchild,Visit)) if (Visit(T->data)) return OK; return ERROR; }else return OK; }//PostOrderTraverse
中序遍历进行中序线索化
void InThreading(BiThrTree p){ // 一个全程指针pre if (p){ InThreading(p->lchild); //左子树线索化 if (!p->lchild){ p->LTag=Thread;p->lchild=pre;} //前驱线索 if (!pre->rchild){ pre->RTag=Thread; pre->rchild=p;} //后继线索 pre=p; //保持pre指向p的前驱 InThreading(p->rchild); //右子树线索化 } }//InThreading

线索二叉树结点的结构:

0 lchild域指示其左孩子 ltag ={ 1 lchild域指示其前驱 0 rchild域指示其右孩子 rtag ={
1 rchild域指示其后继 线索二叉树 线索化 lchild ltag data rtag rchild 线索链表 线索

中序线索二叉树
NIL a + * e / f
NIL
+ 1 b 1 0 / 0 *
b c
d e
f
中 序 线 索 二 叉 树 中 查找结点的后继和前驱:

如何在中序线索二叉树中找结点的后继:
• rtag = 1时,rchild所指的结点即为后继; • rtag = 0时,其后继为遍历其右子树时的第一个结点 (最左下结点)。 • 如结点 “*”的后继是“c” 。
6.3遍历二叉树和线索二叉树
6.3.1遍历二叉树 如果按某条搜索路径巡 访树中每个结点,使得 每个结点均被访问一次 , 而且仅被访问一次。

A B C E D F
G
先序遍历二叉树的操作定义为:
若二叉树为空,则空操作; 否则 (1)访问根结点; (2)先序遍历左子树; (3)先序遍历右子树。
实验与习题
理论习题
6.12-6.16,6.23 实验算法题: 6.37

如何在中序线索二叉树中找结点的前驱:
• ltag = 1时,lchild所指的结点即为前驱; • ltag = 0时,其前驱为遍历其左子树时的最后一个结 点(最右下结点)。 • 如根结点 “-”的前驱是“d” 。
中序线索二叉树
// 二叉树的二叉线索存储表示 typedef enum {Link,Thread} PointerTag; //Link==0:指针,Thread==1:线索 typedef struct BiThrNode { TElemType data; struct BiThrNode *lchild,*rchild; //左右孩子指针 PointerTag LTag,RTag; //左右标志 }BiThrNode, *BiThrTree;

中序遍历二叉树的非递归算法 示意图
A GetTop<-- NULL C p B A S

Pop
p A S
B C D F

E G
CBDFA
CBDFAGE
例: 已知结点的先序序列和中序 序列,求整棵二叉树。
先序序列:A
B C D E F G 中序序列:C B E D A F G
A C B E D F G B C D E A F G B C E D A F G
构造二叉链表表示的二叉树 的递归算法
Status CreateBiTree(BiTree &T) { scanf(“%c”,&ch); if (ch==‘#’) T=NULL; else { if (!(T=(BiTNode *) malloc(sizeof (BiTNode)))) exit(OVERFLOW); T->data = ch ; CreateBiTree(T->lchild); CreateBiTree(T->rchild); } return OK; }//CreateBiTree
例如: 将下列二叉链表改为中序线索链表
1 2 3 4 5 6 7 8 9 10 11 12 13 14
Info A Ltag Lchild 2 Rtag Rchild 3
B 4 5
C 6 0
D E 0 0 7 8
F G H
I
J
K L M N 0 0 0 0 0
0 10 0 12 13 0 9 11 0 0

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

A B C D F G E
CBDFAG E
中序遍历二叉树示例
中序遍历二叉树得: a+b*(c-d)-e/f + a b c * e
/
f
d
中序遍历二叉树的递归算法

A B C D F G E
ABCDFEG
先序遍历二叉树的递归算法
Status PreOrderTraverse(BiTree T, Status(* Visit)(TElemType e)){ if (T){ if (Visit(T->data)) if (PreOrderTraverse(T->lchild,Visit)) if (PreOrderTraverse(T->rchild,Visit)) return OK; return ERROR; }else return OK; }//PreOrderTraverse
0
1
A
C
E G F
D
H
K L
I
J
M
N
中序遍历二叉线索树T的非递归算法:
Status InOrderTraverse_Thr(BiThrTree T, Status(*Visit)(TElemType e)){ // T指向头结点,头结点的左链lchild 指向根结点, //可参见线索化算法。中序遍历二叉线索树T的非递归算法, // 对每个数据元素调用函数Visit. p=T->lchild; //p指向根结点 while(p!=T){ //空树或遍历结束时,p==T while(p->LTag==Link)p=p->lchild;//p寻找最左下结点 if (!Visit(p->data)) return ERROR; //访问其左子树为空的结点 while(p->RTag==Thread&&p->rchild!=T){ p=p->rchild; Visit(p->data); //访问后继结点 } p=p->rchild; } return OK; }//InOrderTraverse_Thr
中序遍历二叉树T,并将其中序线索化:
(为了记下遍历过程中访问结点的先后次序,附设一个全程 指针pre)
Status InOrderThreading(BiThrTree &Thrt, BiThrTree T) { // Thrt指向头结点。 if (!(Thrt=(BiThrTree)malloc(sizeof(BiThrNode)))) exit (OVERFLOW); Thrt->LTag=Link; Thrt->RTag=Thread; //建头结点 Thrt->rchild=Thrt; //右指针回指 if (!T)Thrt->lchild=Thrt; //若二叉树空,则左指针回指 else{ Thrt->lchild=T; pre=Thrt; InThreading(T); //中序遍历进行中序线索化 pre->rchild=Thrt; pre->RTag=Thread; //最后一个结点线索化 Thrt->rchild=pre; } return OK; }//InOrderThreading
相关文档
最新文档