线索化二叉树

前驱节点和后继节点
在这里插入图片描述
上面的二叉树经过中序遍历后的结果为:
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;

分析:如下图为我们想得到的线索化二叉树
在这里插入图片描述

  1. 如果这个节点的左指针为空那么就将他的左指针指向前驱节点,然后改变一下这个节点的类型(将这个类型标记为指向前驱节点)。
  2. 接下来处理右指针(难点)以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
如上图所示

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值