线索二叉树
在二叉树的结点上加上线索的二叉树称为线索二叉树,对二叉树以某种遍历方式(如先序、中序、后序或层次等)进行遍历,使其变为线索二叉树的过程称为对二叉树进行线索化。
概念
了解概念之前我们需要知道为什么需要线索二叉树;
在一些日常问题中我们如果寻找特定遍历序列中二叉树结点的前驱和后继??
- 解决方法:
1.通过遍历寻找——费时间
2.再增设前驱、后继指针域——增加了存储负担
3.利用二叉链表的空指针域
空指针域相关知识如下图所示:
利用二叉链表中的空指针域:
如果某个结点的左孩子为空,则将空的左孩子指针域改为指向其前驱;如果某结点的有孩子为空,则将空的右孩子指针域改为指向其后继
———这种改变指向的指针称为“线索”
这种加上了线索的二叉链表称为线索链表,加上了线索的二叉树称为线索二叉树(Threaded Binary Tree)
特点
- 优势
(1)利用线索二叉树进行中序遍历时,不必采用堆栈处理,速度较一般二叉树的遍历速度快,且节约存储空间。
(2)任意一个结点都能直接找到它的前驱和后继结点。 - 不足
(1)结点的插入和删除麻烦,且速度也较慢。
(2)线索子树不能共用。
举例实施
指向其前驱和后继,指的是按照如图所示的中序遍历,例如G有两个空指针域,并且
G存在前驱和后继,即前空指针域指向其前驱,后空指针域指向其后继。
但是,从中我们也发现一些问题。怎么区分结点的指针到底是指向孩子的指针,还是指向前驱或后继呢?
为区分lrchild和rchild指针到底是指向孩子的指针,还是指向前驱或者后继的指针,对二叉树中每个结点增设两个标志域ltag和rtag,并约定:
因此,结点的结构为:
线索二叉树的类型定义
typedef struct BiThrNode
{
TElemType data;
struct BIThrNode *lchild,rchild; //左右孩子指针
int LTag,RTag; //左右标志
} BiThrNode,*BiThrTree;
先序线索二叉树
中序线索二叉树
后序线索二叉树
最后增加一个头结点