前驱节点和后继节点
上面的二叉树经过中序遍历后的结果为:
4 2 5 1 6 3
那么2的前驱节点为4,2的后继节点为5,4没有前驱节点,3没有后继节点。
线索化二叉树
中序线索化二叉树
如上图可以看到4,5,6的左右指针都为空,当这些指针为空时,将左指针指向前驱节点,右指针指向后继节点,这就是线索化二叉树。
举两个例子:
- 以4节点为例它的左指针应该为null,右指针应该指向节点2,因为节点2是节点4的后继节点
- 以5节点为例那么它的左指针应该指向节点2,右指针应该指向节点1
代码实现
先创建树节点的类:比起正常的二叉树多了
leftType:如果等于0则指向的是左子树,如果为1则指向前驱节点
public int leftType;
rightType:如果等于0则指向的是右子树,如果为1则指向后继节点
public int rightType;
左节点类型leftType和右节点类型rightType两个属性表示这两个指针是用来指向树还是前驱或者后继节点。
package threadedbinarytree;
//线索化二叉树
public class Node {
public int no;
public String name;
public Node left;
public Node right;
//leftType:如果等于0则指向的是左子树,如果为1则指向前驱节点
public int leftType;
//rightType:如果等于0则指向的是右子树,如果为1则指向后继节点
public int rightType;
public Node(int no, String name) {
super();
this.no = no;
this.name = name;
}
@Override
public String toString() {
return "Node [no=" + no + ", name=" + name + "]";
}
public Node() {
super();
}
}
中序线索化二叉树:
package threadedbinarytree;
public class ThreadedBinaryTree {
public Node root = null;
//pre指的是这个节点的前驱节点
public Node pre = null;
/**
* 中序线索化二叉树*/
public void threadNodes(Node node){
if(node == null){
return ;
}
//先线索化左子树
if(node.left != null){
threadNodes(node.left);
}
//线索化这个节点,处理这个节点的前驱节点
if(node.left == null){
node.left = pre;
node.leftType = 1;
}
//处理这个节点的后继节点
if(pre != null && pre.right == null){
pre.right = node;
pre.rightType = 1;
}
pre = node;
//线索化右子树
if(node.right != null){
threadNodes(node.right);
}
}
public ThreadedBinaryTree(Node root) {
super();
this.root = root;
}
}
重点代码
//线索化这个节点,处理这个节点的前驱节点
if(node.left == null){
node.left = pre;
node.leftType = 1;
}
//处理这个节点的后继节点
if(pre != null && pre.right == null){
pre.right = node;
pre.rightType = 1;
}
pre = node;
分析:如下图为我们想得到的线索化二叉树
- 如果这个节点的左指针为空那么就将他的左指针指向前驱节点,然后改变一下这个节点的类型(将这个类型标记为指向前驱节点)。
- 接下来处理右指针(难点)以4节点为例如果我们想让4节点的右节点指向2节点,但是在循环的时候并不知道这个节点的后继是哪个节点,但是在线索化二叉树的时候,这个节点的后继节点的前驱节点就为这个节点,所以我们可以通过操作2节点的前驱节点来让4节点的后继节点指向2节点
if(pre != null && pre.right == null){
pre.right = node;
pre.rightType = 1;
}
package threadedbinarytree;
public class Demo {
public static void main(String[] args) {
Node root = new Node(1,"aa");
Node node2 = new Node(2,"bb");
Node node3 = new Node(3,"cc");
Node node4 = new Node(4,"dd");
Node node5 = new Node(5,"ee");
Node node6 = new Node(6,"ff");
root.left = node2;
root.right = node3;
node2.left = node4;
node2.right = node5;
node3.left = node6;
ThreadedBinaryTree tbt = new ThreadedBinaryTree(root);
tbt.threadNodes(root);
System.out.println(node5.left);
System.out.println(node5.right);
System.out.println(node3.right);
}
}
验证:
本来node5.left和node5.right都应该为null经过线索化
node5.left == node2
node5.right == node1
如上图所示