搬家后的博客链接: IT客栈 www.itkezhan.org
线索二叉树分为五个域(域:装数据的变量)
分别是 LchildLtag data Rtag Rchild
Ltag 和 Rtag 是一个标识变量,又称为控指针
Ltag 控制(标识) Lchild 中的内容性质
Rtag 控制(标识) Rchild 中的内容性质
data 是存放这个结点实际的数据(用户放进来的数据)
当 Ltag = 0 时
Lchild中存放的是指向左孩子的指针
当 Ltag = 1 时
Lchild中存放的是指向前驱的指针,前驱,后继,后面再解释
当 Rtag = 0 时
Rtag中存放的是指向右孩子的指针
当 Rtag = 1 时
Rtag中存放的是指向后继的指针
二叉树的遍历有三种 先序遍历、中序遍历、后序遍历
遍历的意思在这里通俗地解释一下。
相当与你家里有10个碗。你这些碗上面有标号,你从标号1 到 标号 10按照顺序把碗洗一遍。这时候是遍历了一次这些碗。不过你也可以从标号 1 到 标号 10 按照顺序给这些碗放入白饭。对碗的处理就看你喜欢了。还有上面的按照顺序。这个顺序也是可以由你自己来定的。你想从 1 – 10 或者 10 - 1 或者先洗偶数标号的再洗奇数的碗也可以。说白了就是在一个集合中走了一遍,在走的过程中你对这个集合里面的单元进行了某些处理。有点啰嗦。我们继续。
线索二叉树用的是 中序遍历
如图
中序遍历:D、B、G、E、A、C、F、H (关于这些是怎么出来的,看这篇文章)
什么是前驱什么是后继: 其中 B 的前驱是 D 、 B 的后继是 G
写这篇文章的目的在于记录下线索二叉树中前驱后继的查询
查询前驱算法简述
1. 当 p -> Ltag=1时,p->Lchild 指向 p 结点的前驱。
2. 当 p –> Ltag=0 时,p->Lchild 指向左孩子。
P 的前驱结点,是在中序遍历 p 的左子树中的最右侧分枝中没有孩子的结点。形象地说是p为根的左子树中的“最右侧最下端”结点。
查询后继算法简述
1. 当p->Rtag=1时,p->Rchild 指向 p 结点的后继
2. 当p->Rtag=0时,p->Rchild 指向右孩子,于前驱相似,此时 p 的中序后继结点为其右子树的“最左侧下端”的结点
下面是两个查询的代码描述
查询前驱
void InPre(BiTNode *p, BItNOde *pre) { if(p->Ltag == 1) pre = p -> Lchild; else { for(q=p->Lchild; q-Rtag == 0; q=q->Rchild); pre = q; } }
查询后继
void InSucc(BiTNode *p, BiTNode *next) { if(p->Rtag == 1) next = p->Rchild; else { for(q=Rtag->Rchild; q->Ltag; q=q->Lchild); next = q; } }