线索二叉树
中序线索二叉树
二叉树的性质导致有n+1个空指针域
这些空指针域,就可以用来存储,对应节点在中序遍历对应的前驱和后继
这里的前驱和后继不是树里面的是DGBEAFC这个比如G的前驱就是D后继就是B
来储存这些节点
这样的话从数的如何一个节点出发,来推它的中序遍历就看起来更可行了
但是如果是B这种节点它的右子节点是指向对应的右子树,而不是后继怎么办?,这个问题我们放在下面探索
线索二叉树的优点:找节点的前驱后继方便,遍历也方便
线索二叉树的储存结构
先序和后序线索二叉树
二叉树的线索化(代码实现)
找中序前驱线索化之前的方法
在中序遍历的visit()方法中插入操作
当对应的q节点等于我们想要找的p节点
那么pre节点就是p节点对应的中序前驱(中序序列中的前驱,不是树)
用这个思想构造线索二叉树
中序线索化
InThread操作就是新访问到的节点赋给p
原理:还是pre和q两个指针
进行一个中序遍历,在visit()中进行一些小操作
每个结构体定义两个变量,ltag和rtag(左线索标记和右线索标记)
当他们为1的时候指向的就是前驱节点喽
当p指向节点没有左孩子,用其左指针指向pre(前驱)
若pre对应节点没有右孩子,用其右指针指向p(后继)
此时注意第7个节点
最后也不会vist别的了
然后可能他没有右子树,所以
最后做一个检测
检查最后一个节点有没有右子树,没有的话指向NULL,rtag=1
注意中序遍历中最后一个被访问的节点肯定是没有右孩子的!!(按照左根右输出,如果有右孩子就不是最后一个节点)
对应的初始化
的完整代码
两种代码
本质都一样
先序线索化
和之前中序线性化一样
有一个问题
根左右,如果对应的左孩子没有,不就指向pre了吗
然后再访问左孩子就回到pre形成无限循环
解决:看ltag,ltag=0访问左子树,不等于0,直接访问右子树
后序线索化
这里不会出现转圈问题奥
小总结
在线索二叉树找前驱/后继
中序线索二叉树
找指定节点的中序后继next
理论实现
1.当rtag为1的话next就是对应后继
2.当rtag不为1时,按照中序遍历左中右进行遍历的原则
应该是最左下角的元素先被访问从而其为p的后继节点
代码实现
找前驱思路
代码实现
先序线索二叉树
找先序后继
找先序前驱(二叉链表的话)
如果是三叉链表(p有一个指针指向父节点)
4.如果p为根节点就没有先序前驱
后序线索二叉树
二叉链表(不能直接找到后续)
三叉链表