中序线索化二叉树

为什么要线索化二叉树?

答:对于如下一颗二叉树, 中序遍历二叉树结果为4,2,5,1,3那么我想知道5前面的数是什么,就必须要先中序遍历一遍然后再去查询5前面的数字。那么如果我这样操作:对于左右子节点为null的节点,它的左节点指向前一个节点,右节点指向下一个节点,同时标记指针置为1,这样的话,我就可以直接知道中序遍历时5的前一个节点和后一个节点。

这个对二叉树的操作过程叫:线索化二叉树,可知有中序、前序、后序线索化二叉树的方法。得到的树为线索二叉树。

线索化二叉树时,一个节点的前一个节点,叫前驱节点。

线索化二叉树时,一个节点的后一个节点,叫后继节点

对上面二叉树的中序线索化的结果为:

前序线索化的结果为:

后序线索化的结果为:

(中序线索化二叉树以及中序后继遍历和中序前驱遍历)实现代码如下:

public class ThreadBinaryTree {
	private static Node preNode;
	static class Node{
		int value;
		Node left;
		Node right;
		boolean isLeftThread = false;
		boolean isRightThread = false;
		
		public Node(int value) {
			this.value = value;
		}
	}
	/**数组构建一棵完全二叉树
	 * @param arr:数组
	 * @param index:数组下标索引
	 * @return
	 */
	public static  Node createBinaryTree(int[] arr, int index) {
		Node node = null;		  
        if(index < arr.length) {
            node = new Node(arr[index]);
            node.left = createBinaryTree(arr, index * 2 + 1);
            node.right = createBinaryTree(arr, index * 2 + 2);
        }  
        return node;       
	}
	/**中序线索化二叉树
	 * @param node
	 */
	public static  void middleThreadBinaryTree(Node node) {
		if(node !=null) {
			middleThreadBinaryTree(node.left);
			//左指针为空,将左指针指向前一个节点
			if(node.left ==null) {
				node.left =preNode;
				node.isLeftThread = true;
			}
			//前一个节点不为空,且前一个节点的右节点为空
			if(preNode !=null&&preNode.right==null) {
				preNode.right = node;
				preNode.isRightThread = true;
			}
			preNode = node;
			middleThreadBinaryTree(node.right);
		}		
	}
	//中序遍历线索二叉树,按照后继方式遍历
	public static void middleListShow(Node node) {
		System.out.println("哈哈哈");
		//找到最左边的节点
		while(node!=null&&!node.isLeftThread) {
			node = node.left;
			System.out.println(node.value);
		}	
		System.out.println("哈哈哈");
		while(node !=null) {
			System.out.print(node.value +" ");
			//判断node的左子树是否为空
			if(node.isRightThread) {
				node = node.right;
			}else {
				//如果node的左节点不为空,找最左边的节点
				node = node.right;
				while(node !=null&&!node.isLeftThread) {
					node = node.left;
				}
			}			
		}
	} 
	//按照前驱方式中序遍历二叉树
	public static void middlePreShow(Node node) {
		//找最右边的一个节点
        while(node.right != null && !node.isRightThread) {
            node = node.right;
        }
 
        while(node != null) {
            System.out.print(node.value + ", ");
 
            //如果左指针是线索
            if(node.isLeftThread) {
                node = node.left;
 
            } else {   
            	//如果左指针不是线索,找到左子树开始的节点
                node = node.left;
                while(node.right != null && !node.isRightThread) {
                    node = node.right;
                }
            }
        }
	}
	
    public static void main(String[] args) {
		int[] arr = new int[] {12,32,11,9,4,5,2,34,21,20};
        //创建完全二叉树
		Node nod = createBinaryTree(arr,0);	
        //中序线索化二叉树
		middleThreadBinaryTree(nod);	
        //中序后继遍历
		middleListShow(nod);	
		System.out.println();
        //中序前驱遍历		
		middlePreShow(nod);
	}
}

 

  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值