线索二叉树基本概念
遍历二叉树可以按一定规则得到一个线性序列(先序序列、中序序列、后序序列)。这些序列除头尾之外,都有且仅有一个前驱和一个后继。
当遍历二叉树时,只能得到结点的左右孩子信息,而不能直接得到结点的前驱和后继信息,只能从根节点遍历得到,由此引入线索二叉树。
线索二叉树就是为了加快查找结点前驱和后继的速度。
规定:
若结点有左孩子,则 lchild 域指向其左孩子,否则, lchild 域指向其前驱;
若结点有右孩子,则 rchild 域指向其右孩子,否则, rchild 域指向其后继;
为了避免混淆,在原来的结点基础上增加两个表示域:
lchild | ltag | data | rchild | rtag |
---|
ltag = 0:lchild 域指向结点左孩子
ltag = 1:lchild 域指向结点前驱
rtag = 0:rchild 域指向结点右孩子
rtag = 1:rchild 域指向结点后继
以这种结点结构构成的二叉链表作为二叉树的存储结构,叫做线索链表
其中指向结点前驱和后继的指针,叫做线索
加上线索的二叉树,叫做线索二叉树
对二叉树以某种次序遍历使其变为线索二叉树的过程,叫做线索化,线索化的过程就是在遍历的过程中修改空指针的过程。
构造线索二叉树
中序线索二叉树
中序线索二叉树,就是非空二叉树进行中序线索化之后所得到的。
中序序列:a+b*c-d-e/f
树中所有叶子结点的右链是线索,则右链直接指向了结点的后继;b结点的后继为 * 。
非叶子结点右链是指针,无法得到后继信息。
根据中序遍历的规律知:
结点的后继:遍历其右子树时访问的第一个结点,即右子树中最左下的结点;
结点的前驱:若没有左孩子其左标志为 1 ,则左链为线索,指向其前驱 ;否则,遍历左子树时最后一个访问的结点(左子树中最右下的结点)位其前驱。
先序线索二叉树
先序序列:-+a*b-cd/ef
黄色结点有左孩子,无法记录其前驱结点,则找不到其前驱结点。
根据先序遍历的规律知:
结点的后继:若有左孩子,则左孩子就是其后继,若没有左孩子但有右孩子,则右孩子就是其后继,若是叶子结点右标志为1,则右链为线索,指向其后继;
结点的前驱:若没有左孩子其左标志为 1 ,则左链为线索,指向其前驱 ;否则,有左孩子,无法存储左链,不能直接找到其前驱结点。
后序线索二叉树
后序序列:abcd-*+ef/-
黄色结点有左孩子,无法记录其前驱结点,则找不到其前驱结点。
根据后序遍历的规律知:
结点的后继:
1、若结点是二叉树的根,则后继为空;
2、若结点是其双亲的右孩子,或是其双亲的左孩子且其双亲没有右子树,则其后继就是其双亲结点;
3、若结点是其双亲的左孩子,且其双亲有右子树,则其后继为双亲的右子树上按后序遍历列出的第一个结点
结点的前驱:若没有左孩子其左标志为 1 ,则左链为线索,指向其前驱 ;否则,有左孩子,无法存储左链,不能直接找到其前驱结点。