线索二叉树
在二叉树的结点上加上线索的二叉树称为线索二叉树,对二叉树以某种遍历方式(如先序、中序、后序或层次等)进行遍历,使其变为线索二叉树的过程称为对二叉树进行线索化。
比较常见的是中序,这里我讲的是中序线索化。
线索化
现将某结点的空指针域指向该结点的前驱后继,定义规则如下:
若结点的左子树为空,则该结点的左孩子指针指向其前驱结点。
若结点的右子树为空,则该结点的右孩子指针指向其后继结点。
这种指向前驱和后继的指针称为线索。将一棵普通二叉树以某种次序遍历,并添加线索的过程称为线索化。

构建线索二叉树
这里要注意的是
若结点的右子树为空,则该结点的右孩子指针指向其后继结点。
这里如果前驱的节点的右孩子为空,那么前驱的节点的后继就是当前节点
public void buildDfsMiddle(Node node){
if (node == null) {
return;
}
// 构建左孩子
buildDfsMiddle(node.left);
// 如果左孩子为空,前驱
if(node.left==null){
node.lflag = 1;
node.left = pre;
}
// 如果前驱的节点的右孩子为空,那么前驱的节点的后继就是当前节点
if(pre!=null&&pre.right==null){
pre.rflag = 1;
pre.right = node;
}
pre = node;
// 构建右孩子
buildDfsMiddle(node.right);
}
遍历
中序遍历
中序遍历要注意的是是我们从左子树的最左面开始遍历
然后如果我们有后继,我们就直接遍历后继
如果是右子树,那么我们还要遍历到右子树的最左面的节点
// 线索树中序遍历
public void dfsClueMiddle(Node node){
// 首先中序遍历的第一个遍历是最左面的那个
while (node!=null&&node.lflag!=1){
node = node.left;
}
while (node!=null){
System.out.println(node.val);
if(node.rflag==1){
node = node.right;
}else {
node = node.right;
while (node!=null&&node.lflag!=1){
node = node.left;
}
}
}
}
后序遍历
后序遍历我们要先看还有没有左子树 如果没有左子树那么我们就看有没有右子树
如果都没有,我们就需要看当前的节点的后继的右孩子(这里要注意的是该节点的后继还有后继)
public void dfsClueFront(Node node){
while (node!=null){
System.out.println(node.val);
if(node.lflag!=1){
node = node.left;
continue;
}
if(node.rflag!=1){
node = node.right;
continue;
}
while (node.rflag==1){
node = node.right;
}
node = node.right;
}
}
浙公网安备 33010602011771号