线索二叉树提出的原因:
在普通二叉树中,每个结点都有左右两个指针域,这些指针域都指向结点类型的数据对象,当二叉树稀疏时,很多结点的左右两个指针域就显得浪费存储空间了。因此,提出了一种方法以提高空间利用率,令原来二叉树结点的空指针指向这棵二叉树在某种遍历序列中的前驱结点或后继结点,此时称这个指向某种遍历序列中的前驱或后继结点的指针为线索。
例如,在某棵二叉树的先序遍历序列中,针对某个结点Node:
(1)如果Node.lchild为空,则Node.lchild存放指向先序遍历序列中该结点的前驱结点。这个结点称为Node的先序前驱;
(2)如果Node.rchild为空,则Node.rchild存放指向先序遍历序列中该结点的后继结点。这个结点称为Node的先序后继。
显然,在决定lchild是指向左孩子还是前驱,rchild是指向右孩子还是后继,需要一个区分标志的。因此,我们在每个结点再增设两个标志域ltag和rtag,注意ltag和rtag只是区分0或1数字的布尔型变量,其占用内存空间要小于像lchild和rchild的指针变量。结点结构如下所示。
其中:
(1)ltag为0时指向该结点的左孩子,为1时指向该结点的前驱;
(2)rtag为0时指向该结点的右孩子,为1时指向该结点的后继;
结点类的设计可以是这样的:
下面是先序线索二叉树的示意图:
类似的还有中序、后序线索二叉树等。
线索化的实质就是将二叉链表中的空指针改为指向前驱或后继的线索。由于前驱和后继信息只有在遍历该二叉树时才能得到,所以,线索化的过程就是在遍历的过程中修改空指针的过程。