紧接上一篇文章。。。。
参考资料:
http://www.cnblogs.com/bitzhuwei/p/algorithm-2-threaded-binary-tree.html#_label0
http://www.cnblogs.com/mcgrady/p/3320413.html
一、为什么构造线索二叉树
二叉树中容易找到结点的左右孩子信息,但该结点在某一序列中的直接前驱和直接后继只能在某种遍历过程中动态获得。先依遍历规则把每个结点某一序列中对应的前驱和后继线索预存起来,这叫做"线索化"。
意义:从任一结点出发都能快速找到其某一序列中前驱和后继,且不必借助堆栈。
这就是线索二叉树(Threaded Binary Tree)。
二、线索树节点结构
任意一个二叉树,其结点数为N,则有N+1个空链域。空链域就是叶结点的lchild和rchild。
我们规定:
-
若结点有左子树,则lchild指向其左孩子;否则,lchild指向其直接前驱(即线索);
-
若结点有右子树,则rchild指向其右孩子;否则,rchild指向其直接后继(即线索) 。
那么就有如下一个问题:如何判断是孩子指针还是线索指针?
为了区别孩子指针和线索指针,特此定义如下结构:
标志域只需要2个bit,而用增加指针域的方式则需要2个指针的空间(一个指针就是一个int的长度)。所以这个方案极大地节省了空间。
我们规定:
-
当Tag域为0时,表示孩子情况;
-
当Tag域为1时,表示线索情况。
三、有关术语
线索链表:用含Tag的结点样式所构成的二叉链表。
线 索:指向结点前驱和后继的指针。
线索二叉树:加上线索的二叉树。
线 索 化:对二叉树以某种次序遍历使其变为线索二叉树的过程。
线索化过程就是在遍历过程中修改空指针的过程:
-
将空的lchild改为结点的直接前驱;
-
将空的rchild改为结点的直接后继;
-
非空指针呢?仍然指向孩子结点。(称为"正常情况")