数据结构与算法---线索二叉树

线索二叉树

  • 当用二叉链表作为二叉树的存储结构时,可以很方便地找到某个结点地左右孩子;但一般情况下,无法直接找到该结点在某种遍历序列中地前驱和后继结点。
  • 什么是线索化二叉树:n个结点的二叉链表中含有n+1[ 公式 2n-(n-1)= n +1 ]个空指针域。利用二叉链表中的空指针域,存放指向结点在某种遍历次序下的前驱和后继结点的指针的指针(这种附加的指针称为“线索”)
  • 这种加上了线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树。根据线索性质的不同,线索二叉树可分为前序线索二叉树,中序线索二叉树和后序线索二叉树。
  • 一个结点的前一个结点称为前驱结点
  • 一个结点的后一个结点称为后继结点

在这里插入图片描述
解决左右指针的指向可能为孩子或结点的方法:在结点类中设置属性来区分。

在这里插入图片描述

结点类:
在这里插入图片描述

	private int no;
	private String name;
	private HeroNode left;
	private HeroNode right;
//	1表示指向结点(前、后驱结点),0表示指向树(左、右子树)
	private int leftType;
	private int rightType;
  • 代码实现
	/**
	 * 对二叉树进行中序线索化的方法
	 * 
	 * @param node 就是当前需要线索化的节点
	 */
	public void threadNodes(HeroNode node) {
		if (node == null) {
			return;
		}
		// 先线索化左子树
		threadNodes(node.getLeft());
		// 线索化当前节点
		// 处理当前节点的前驱节点
		if (node.getLeft() == null) {
			// 让当前节点的左指针指向前驱节点
			node.setLeft(pre);
			node.setLeftType(1);
		}
		// 处理后继节点
		// pre!=null的条件非常重要,它决定了第一次
		if (pre != null && pre.getRight() == null) {
			// 让前驱节点的右指针指向当前节点
			pre.setRight(node);
			// 修改前驱节点的右指针类型
			pre.setRightType(1);
		}
		// 每处理一个节点,让当前节点是下一个节点的前驱节点
		pre = node;
		// 线索化右子树
		threadNodes(node.getRight());
	}

图解:
图解

  • 遍历线索化二叉树
    说明:因为线索化后,各个结点的指向有变化,因此原来的遍历方式不能使用,各个结点可以通过线性方式遍历,无需使用递归方式,也提高了遍历的效率。遍历的次序应当和通过前、中、后序线索化一致。
	/**
	 * 遍历中序线索化二叉树的方法
	 */
	public void threadedList() {
//		定义一个变量,存储当前遍历的结点,从root开始
		HeroNode node = root;
		while (node != null) {
//			循环的找到leftType为1的结点,说明该结点是按照线索化后处理的有效结点
			while (node.getLeftType() != 1) {
				node = node.getLeft();
			}
			System.out.println(node);
//			如果当前结点的右指针指向后继结点,则一直输出
			while (node.getRightType() == 1) {
//				获取到当前结点的后继结点
				node = node.getRight();
				System.out.println(node);
			}
//			替换这个遍历的结点
			node = node.getRight();
		}
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值