Java数据结构--线索二叉树

一、线索二叉树的概念

在二叉树的链式存储结构中,增加指向前趋和后续结点的信息,称为线索。加上线索的二叉树称为线索二叉树。对二叉树以某种次序进行遍历使其成为线索二叉树的过程称为线索化。

二、线索化二叉树

在由n个结点构成的二叉树链式存储结构中,存在着n+1个空链域。可以利用这些空链域建立起来相应结点的前趋结点信息和后续结点信息 。在二叉树中,如果某结点有左子树,则其lChind域指向其左孩子,否则其lChild域指向该结点在遍历序序列中的前趋结点;如果其结点有右子树,则其rChild域指向其右孩子,否则其rChild与指向该结点在遍历序列中的后续结点。
为了区分一个结点中lChild域和rChild域指向的是左、右孩子还是前趋、后续,需要在结点中再增设两个线索标志域lTag 和 rTag来区分这两种情况。线索标志域定义如下:
Java数据结构--线索二叉树_第1张图片

因此,每个结点包含5个域。如图2.1所示。

Java数据结构--线索二叉树_第2张图片

在二叉树中,结点的前趋和后续需要根据遍历的不同而不同、因此线索二叉树树叶分为前序线索二叉树、中序线索二叉树和后序线索二叉树。
如图2.2(b)所示图2.2(a)所对应的中序线索二叉树,如图2.2(c)所示为图2.2(a)所示对应的前序线索二叉树树。如图2.2(d)所示为图2.2(a)所对应的后序线索二叉树。

Java数据结构--线索二叉树_第3张图片

和其他结构一样,线索二叉树也包含头结点。头结点的data域为空,lChlid域指向二叉树的根结点,lTag为0,rChild域指向某种遍历的最后一个结点,rTag为1,图2.3所示为图2.2(a)的中序线索链表。

Java数据结构--线索二叉树_第4张图片Java数据结构--线索二叉树_第5张图片

二叉树中序线索化同二叉树中序遍历相似,利用递归实现比较简单。在根结点非空时,线索化其左子树,再处理根结点的前驱和后续,最后线索化其右子树。先手工创建图2.4所示的无头结点的二叉链树,再调用中序遍历线索化算法形成图2.3所示的线索二叉树,同时输出线索化结构,具体代码如下:

public class BinThrTree {
	char data; 			  // 根结点数据
	boolean leftIsThread; // 左孩子是否为线索
	BinThrTree left;	  // 左子树
	boolean rigthIsThread;// 右孩子是否为线索
	BinThrTree right;	  // 右子树
	static BinThrTree pre = null;//线索化的时候保存前驱
	
	public BinThrTree(char data) {
		this.data = data;
		this.leftIsThread = false;
		this.left = null;
		this.rigthIsThread = false;
		this.right = null;
	}
	
	/** 中序线索化二叉树 */
	public static void inThread(BinThrTree root) {
		if (root != null) {
			inThread(root.left); // 线索化左孩子
			if (null == root.left) { // 左孩子为空
				root.leftIsThread = true; // 将左孩子设置为线索
				root.left = pre;
				System.out.println(((pre!=null)?pre.data:"null") + "<-" + root.data);
			}
			if (pre!=null && null==pre.right) { // 右孩子为空
				pre.rigthIsThread = true;
				pre.right = root;
				System.out.println(pre.data + "->" + root.data);
			}
			pre = root;
			inThread(root.right); // 线索化右孩子
		}
	}

	public static void main(String[] args) {
		BinThrTree root = new BinThrTree('A');// 创建二叉树
		root.left = new BinThrTree('B');
		root.right = new BinThrTree('C');

		BinThrTree b = root.right;
		b.left = new BinThrTree('E');
		b.right = new BinThrTree('F');

		inThread(root);	// 二叉树中序线索化
	}
}

三、遍历线索化二叉树

图2.3所示中序线索化二叉树的基础上,讨论中序遍历线索化二叉树,其算法思想是:从根结点开始,只要根结点非空,并且其左孩子不是线索,就循环递进用其左孩子迭代根结点,直到其左孩子是线索为止;然后访问当前根结点;如果右孩子是线索,则迭代线索所指的后续为根结点,访问之,否则存在右孩子,继续循环递进用其左孩子迭代根结点,直到其左孩子是线索为止。在前面线索二叉树代码的基础上,遍历中序线索二叉树的算法代码具体如下

/**
 * *中序遍历线索二叉树
 * 从根结点开始,只要根结点非空,并且其左孩子不是线索,就循环递进用其左孩子迭代根结点,
 * 直到其左孩子是线索为止;然后访问当前根结点;如果右孩子是线索,则迭代线索所指的后续为
 * 根结点,访问之,否则存在右孩子,继续循环递进其左孩子迭代根结点,直到其左孩子是线索为
 * 止。
 */
public static void inThreadOrder(BinThrTree root) {
	if (root != null) {
		while(root!=null && !root.leftIsThread) { //如果左孩子不是线索
			root = root.left; //
		}
		do {
			System.out.println(root.data + ",");
			if (root.rigthIsThread) { // 如果孩子是线索
				root = root.right;
				} else { // 有右孩子
					root = root.right;
					while(root!=null && !root.leftIsThread) {
						root = root.left;
					}
				}
		} while (root!=null);
	}
}

你可能感兴趣的:(Java)