线索二叉树

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

2013-7-7
滨州学院计算机科学技术系
为方便起见,仿照线性表的存储结构,在二叉树的线索链表上也 添加一个头结点,并令其lchild域的指针指向二叉树的根结点, 其rchild域的指针指向遍历时访问的最后一个结点;反之,令二 叉树遍历序列的第一个结点的lchild域的指针和最后一个结点的 rchild域的指针均指向头结点。
A B C D E F G H K
E^ C^
^B
^D^
•包含 “线索” 的存储 结构,称作 “线索链 表” •与其相应的二叉树, 称作 “线索二叉树”
滨州学院计算机科学技术系
2013-7-7
中序线索二叉树
0 1
A 0 A 0
0 B 0 NULL
1 C 0
NULL 1 D 1
1 E 1 1 F 1
2013-7-7
2013-7-7 滨州学院计算机科学技术系
三、二叉树的线索化
•对二叉树以某种次序遍历使其变为线索 二叉树的过程叫做线索化。 •线索化的实质就是将二叉链表中的空指针 改为指向直接前驱或直接后继的线索。 •线索化的过程即为在遍历的过程中修改空指针 的过程,即在“访问根结点”处进行加线索的改 造,就可实现前序、中序和后序的线索化。 •线索化分类 先序线索化
2013-7-7 滨州学院计算机科学技术系
例4:求给定值x的后继结点 例4:求出线索二叉树中给定值x的后继结点
BiThrTree InOrder(BiThrTree T, ElemType x){ p = T->lchild ; //p指向中序线索二叉树的根结点 while(p!=T){ while( p->ltag==0 && p->data!=x ) p = p->lchild ; //在左子树中往左下方向查找x if(p->data==x) return (p); //找到返回p while( p->rtag==1 && p->rchild!=T ){ p = p->rchild ; //后继结点 if(p->data==x) return (p); } p = p->rchild ; //转向右子树寻找 } } 2013-7-7 滨州学院计算机科学技术系
2013-7-7
中序线索化
滨州学院计算机科学技术系
后序线索化
三、二叉树的线索化
例1:画出下面二叉树的 中序线索二叉树 A
方法:在遍历过程 中修改空指针
B NULL D E F C
NULL
G
H
中序遍历序列:D B E G A F H C
2013-7-7 滨州学院计算机科学技术系
例2:二叉树的先序线索化
例3:二叉树的中序线索化算法
BiThrTree pre = NULL ; //设置前驱为全局 void InOrderThread(BiThrTree T){ if(T){ InOrderThread( T->lchild ); //左子树中序线索化 if( !T->lchild ){ //左孩子为空,添加前驱线索 T->ltag = 1 ; T->lchild = pre ; //修改前驱线索为pre } if( pre && pre->rtag==1 ) //前驱结点没有右孩子 pre->rchild = T ; //前驱结点的后继为当前结点 if( !T->rchild ) T->rtag = 1; //置右标记,为后继线索做准备 pre = T ; InOrderThread( T->rchild ); //右子树中序线索化 } 2013-7-7 滨州学院计算机科学技术系 }
2013-7-7 滨州学院计算机科学技术系
2. 线索链表的类型定义:
typedef struct BiThrNod { TElemType data; struct BiThrNode *lchild, *rchild; // 左右指针 int LTag, RTag; // 左右标志 } BiThrNode, *BiThrTree;
例4:求出线索二叉树中给定值x的后继结点
算法思想:
假设在中序线索二叉树进行操作,采用 带头结点的线索链表作为存储结构。首先, 在中序线索二叉树中查找给定值为x的结点, 由p指向;然后,根据指针p在中序线索二叉 树中所指结点的后继结点的特征进行判断。 特征:若p的右标志为1,p的rchild指向其 后继结点;否则,结点p的右子树中最左边 的结点是p的中序后继结点。
※ 中序遍历的第一个结点 ?
左子树上处于“最左下”(没有左子树) 的结点。
※ 在中序线索化链表中结点的后继 ?
若无右子树,则为后继线索所指结点; 否则为对其右子树进行中序遍历时访问 的第一个结点。
2013-7-7 滨州学院计算机科学技术系
void InOrderTraverse_Thr (BiThrTree T) { p = T->lchild; // p指向根结点 while (p != T) { // 空树或遍历结束时,p= =T while (p->LTag==0) p = p->lchild; // 找到第一个结点 print(p->data)//访问结点 while (p->RTag==1&& p->rchild!=T) { //有右线索时找其右线索 p = p->rchild; print (p->data); // 访问结点 } p = p->rchild; // p进至其右子树根 } } // InOrder
滨州学院计算机科学技术系
一、 何谓线索二叉树?
遍历二叉树的结果是,求得结点的一 线性序列,对非线性结构进行线性化操作。
A
B
C
D
2013-7-7
例如: 先序序列: ABCDEFGHK E 中序序列: F B D CAH G K F E K
滨州学院计算机科学技术系
G H
后序序列: DCBHKGFEA
•若将指向该线性序列中的“前 驱”和 “后继” 的指针,称作 “线索”
算法思想: 对二叉树进行先序遍历,在“访问结点” 时根据有无左右孩子判断决定进行加线索的 改造。没有左孩子添加前驱线索,没有右孩 子添加后继线索。 算法要点: 需要设一个指针pre始终指向当前访问结 点的前驱
2013-7-7 滨州学院计算机科学技术系
二叉树的先序线索化算法
BiThrTree pre = NULL ; //设置前驱为全局变量 void PreOrderThread(BiThrTree T){ if(T){ if( !T->lchild ){ //左孩子为空,添加前驱线索 T->ltag = 1 ; T->lchild = pre ; //修改前驱线索为pre } if( pre && pre->rtag==1 ) //前驱结点没有右孩子 pre->rchild = T ; //前驱结点的后继为当前结点 if( !T->rchild ) T->rtag = 1; //置右标记,为后继线索做准备 pre = T ; if( T->ltag==0 ) PreOrderThread( T->lchild ); //左子树前序线索化 PreOrderThread( T->rchild ); //右子树前序线索化 2013-7-7 } 滨州学院计算机科学技术系 }
BiThrTree AfterXNode(BiThrTree T){ BiThrTree p =InOrder(T,x);
//在T树上查找给定值x的结点,由p指向
if( p->rtag==1 ) return (p->rchild) ;
//右标志为1,p的rchild指向其后继结点
else{ q = p->rchild ; //右标志为0,进入右子树 while( q->ltag==0 ) q = q ->lchild ; //右子树中最左下的结点为所求后继 return (q);
thrt 0 1
0A0 0B0 1D1 1E0 1G1
2013-7-7 滨州学院计算机科学技术系
0C1 1F0 1H1
二、 线索链表的遍历算法 由于在线索链表中添加了遍历中 得到的“前驱”和“后继”的信息, 从而简化了遍历的算法。
2013-7-7
滨州学院计算机科学技术系
例如:遍历中序线索化链表的算法
滨州学院计算机科学技术系
1.对线索链表中结点的约定:
在二叉链表的结点中增加两个标志域, 并作如下规定: 若该结点的左子树不空, 则源自文库child域的指针指向其左子树, 且左标志域的值为0 “指针”; 否则,Lchild域的指针指向其“前驱”, 且左标志的值为1
2013-7-7
“线索” 。
滨州学院计算机科学技术系
// Link==0:指针,Thread==1:线索
typedef struct BiThrNod { TElemType data; struct BiThrNode *lchild, *rchild; // 左右指针 PointerThr LTag, RTag; // 左右标志 } BiThrNode, *BiThrTree;
2013-7-7 滨州学院计算机科学技术系
数据结构
第六章
树和二叉树
线索二叉树
学习资料邮箱:ds_study@163.com 密码:ds2013 系内数据结构学习网站:http://10.2.4.200:8080/ds
2013-7-7
滨州学院计算机科学技术系
本讲内容
一、何谓线索二叉树?
二、线索链表的遍历算法 三、二叉树的线索化
2013-7-7
} }
2013-7-7 滨州学院计算机科学技术系
例5:求后序线索树中给定结点的直接前驱 算法思想 二叉树的后序遍历是“左-右-根”,因此, 在后序线索二叉树中,若结点有右孩子,则右 孩子是其后序前驱;否则,左指针(或左线索) 就是其后序前驱。
BiThrTree PostFront(BiThrTree T,BiThrTree p){ if( p->rtag==0 ) //若p有右孩子,则右孩子为其前驱 return (p->rchild) ; else{//若p无右孩子,则左孩子或左线索为其直接前驱 return (p->lchild); } }
若该结点的右子树不空, 则rchild域的指针指向其右子树, 且右标志域的值为 0 “指针” ; 否则,rchild域的指针指向其“后继”,
且右标志的值为1 “线索”。
如此定义的二叉链表称作“线索链表”。
2013-7-7
滨州学院计算机科学技术系
2. 线索链表的类型定义:
typedef enum { Link, Thread } PointerThr;
相关文档
最新文档