为什么要研究线索二叉树
当用二叉链表作为二叉树的存储结构时,可以很方便的找到某个结点的左右孩子;但一般情况下,无法直接找到该结点在某种遍历序列中的前驱和后继结点
如何寻找特定序列中二叉树结点的前驱和后继???
解决方法:
- 1、通过遍历寻找——费时间
- 2、再增设前驱、后继指针域——增加了存储负担
- 3、
利用二叉链表的空指针域(√)
综合考虑,我们选用第三种方法
回顾:二叉链表中空指针域的数量
具有 n 个结点的二叉链表中,一共有 2n 个指针域;因为 n 个结点中有 n-1 个孩子,即 2n 个指针域中,有 n-1 个用来指示结点的左右孩子,其余 n+1 个指针域为空
利用二叉链表中的空指针域
如果某个结点的左孩子为空,则将空的左孩子指针域改为指向其前驱;如果某个结点的右孩子为空,则将空的右孩子指针域改为指向其后继;
———这种改变指向的指针称为“线索”
加上了线索的二叉树称为线索二叉树
,对二叉树按,某种遍历次序使其变为线索二叉树的过程叫线索化
这就是一棵线索二叉树:
ltag与rtag
图中的蓝色和红色箭头(指针)到底是指向孩子的指针还是指向前驱或后继的指针呢???
为了区分这个,我们对二叉链表中每个结点增设两个标志域 ltag 和 rtag,并约定:
这样,结点的结构为:
线索二叉树的类型定义
二叉树的二叉线索类型定义如下:
typedef struct BiThrNode
{
TElemType data;
struct BIThrNode *lchild,rchild; //左右孩子指针
int LTag,RTag; //左右标志
} BiThrNode,*BiThrTree;
先序、中序、后序线索二叉树
先序线索二叉树:
中序遍历二叉树:
后续遍历二叉树:
增设头结点
练习一下:
可以看出图中有两个指针悬空,为了操作方便,我们可以增加一个头结点,让这个空的指针指向头结点
增设一个头结点:
(这个头结点也是由五个部分组成data、ltag、lchild、rtag、rchild)
增设头结点后,处理起来会更方便
借鉴:《数据结构》严蔚敏 青岛大学—王卓