引言
很多时候我们需要先手动对树进行一些分析,再考虑使用什么样的结构去编程,所以手算去分析一颗树也是十分重要的。
对于二叉树,我们可以将它改造为线索树,也就将左空指针指向其前驱结点,右空指针指向其后继结点。
本文记录了一种利用标记对快速求解中序遍历下二叉树结点前驱后继的方法,但注意,我们分析的目的是线索化,所以本方法只对空指针有效,即计算左空指针应指向的前驱结点和右空指针应指向的后继结点。
问题假设
如图所示有14个结点的二叉树,我们现在随便选取一个结点,比如结点10,熟悉二叉树的人一眼就可以看出结点10的中序前驱结点是2(后继没有考虑的意义,我们只需要考虑空指针的位置)
再比如,结点12的前驱是结点6,后继是结点3。但随着树的增大,这样看会越来越慢,且每次只能一个一个去往上查,效率低还容易出错。这里记录一种计算方法,能更直观和更快的反映出每个结点的前后驱关系。
方法给出
我们用一对数来标记每一个结点,其中结点1设为
,其余结点的标记对用以下规则求出:
- 若结点为父节点
的左儿子,则它的标记对为
- 若结点为父节点
的右儿子,则它的标记对为
总结来说,就是从结点顺着左边下滑,下一个结点的下标不变,
下标加1。反之,顺着右边下滑,代表同方向的
下标不变,逆方向的
下标加1。
我们将上树中的标记对都填上:
则每个结点的
- 前驱结点为:离它最近,且L下标为它的L下标减一的结点
- 后继结点为:离它最近,且R下标为它的R下标减一的结点
比如结点12,标记对为,将标记对下标全减一,得到
,则前驱结点为离它最近且标记对有
的结点,即结点6;后继结点为离它最近且标记有
的结点,即结点3。
同理,结点10的前驱为2。
对于结点8,后继为结点4,前驱下标为,即不存在前驱,因为结点8是中序遍历序列中的第一个。同理结点7没有后继。
再次注意,我们只是考虑结点空指针应该怎么指向,也就是线索化二叉树时的做法,对于非空指针是无效的。比如结点6,它的前驱可以用此方法求出,为结点1,但后继用此方法明显是错的(不过指针非空,前驱后继关系应该很明显吧)。