线索化二叉树与遍历(中序)

  1. n个结点的二叉链表中含有n+1 [公式2n-(n-1)=n+1] 个空指针域。利用二叉链表中的空指针域,存放指向该结点在某种遍历次序下的前驱和后继结点的指针(这种附加的指针称为"线索" )
  2. 这种加上了 线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树(Threaded BinaryTree)。根据线索性质的不同,线索二叉树可分为前序线索二叉树、中序线索二叉树和后序线索二叉树三种
  3. 一个结点的前一个结点,称为前驱结点
  4. 一个结点的后一个结点,称为后继结点

将下面的二叉树,进行中序线索二叉树。中序遍历的数列为{8,3, 10,1, 14, 6}
在这里插入图片描述
在这里插入图片描述说明:当线索化二叉树后,Node 节点的属性left 和right ,有如下情况:
left指向的是左子树,也可能是指向的前驱节点.比如①节点left指向的左子树,而面节点的left 指向的就是前驱节点
right指向的是右子树,也可能是指向后继节点,比如①节点right指向的是右子树,而0节点的right指向的是后继节点

遍历线索化二叉树

说明:对前面的中序线索化的二叉树,进行遍历
分析:因为线索化后,各个结点指向有变化,因此原来的遍历方式不能使用,这时需要使用新的方式遍历线索化二叉树,各个节点可以通过线型方式遍历,因此无需使用递归方式,这样也提高了遍历的效率。遍历的次序应当和中序遍历保持一致。

public class ThreadedBinaryTreeDemo {

	public static void main(String[] args) {
	//测试中序线索二叉树功能
		ThreadedBinaryTree binaryTree = new ThreadedBinaryTree();
		HeroNode root = new HeroNode(1,"菲兹");
		HeroNode n2 = new HeroNode(3,"维恩");
		HeroNode n3 = new HeroNode(6,"奎因");
		HeroNode n4 = new HeroNode(8,"潘森");
		HeroNode n5 = new HeroNode(10,"维克多");
		HeroNode n6 = new HeroNode(14,"菲奥娜");
		//简单处理手动创建
		root.setLeft(n2);
		root.setRight(n3);
		n2.setLeft(n4);
		n2.setRight(n5);
		n3.setLeft(n6);
		binaryTree.setRoot(root);
		binaryTree.threadedNodes();
		HeroNode le = n5.getLeft();
		HeroNode ri = n5.getRight();
		System.out.println(le);
		System.out.println(ri);
		
		System.out.println("线索化遍历");
		binaryTree.threadedList();

	}

}

//定义ThreadedBinaryTree二叉树
class ThreadedBinaryTree{
	private HeroNode root;
	//为实现线索化 需要创建给指向当前节点的前驱节点的指针
	//在递归线索化时 pre总是保留前一个节点
	private HeroNode pre = null;
	public HeroNode getRoot() {
		return root;
	}
	public void setRoot(HeroNode root) {
		this.root = root;
	}
	//重载方法
	public void threadedNodes() {
		this.threadedNodes(root);
	}
	//编写对二叉树进行中序线索化的方法
	//node就是当前需要线索化的节点
	public void threadedNodes(HeroNode node) {
		if(node == null) {
			return;
		}
		//1.先线索化左子树
		threadedNodes(node.getLeft());
		//2.线索化当前节点
		//处理当前节点的前驱节点
		if(node.getLeft() == null) {
			//让当前节点的左指针 指向前驱节点
			node.setLeft(pre);
			//修改当前节点的左指针类型 指向前驱节点
			node.setLeftType(1);
		}
		//处理后继节点
		if(pre!=null && pre.getRight() == null) {
			//让前驱节点的右指针指向当前节点
			pre.setRight(node);
			pre.setRightType(1);
		}
		//每处理一个节点后让当前节点是下一个节点的前驱节点
		pre = node;
		
		//3.再线索化右子树
		threadedNodes(node.getRight());
		
	}
	//中序遍历线索化二叉树
	public void threadedList() {
		//定义一个变量 存储当前遍历的节点 从root开始
		HeroNode node = root;
		while(node != null) {
			//先向左遍历
			while(node.getLeftType() == 0) {//表示不是线索化处理后的
				node = node.getLeft();
				
			}
			System.out.println(node);
			//后继节点则一直输出
			while(node.getRightType() == 1) {
				node = node.getRight();
				System.out.println(node);
			}
			node = node.getRight();
		}
	}
	
	
}

//创建HeroNode节点
class HeroNode{
	private int no;
	private String name;
	private HeroNode left;
	private HeroNode right;
	//如果 leftType == 0 表示指向左子树 1表示指向前驱节点
	//如果 rightType == 0 表示指向左子树 1表示指向后继节点
	private int leftType;
	private int rightType;
	
	/**
	 * @return the leftType
	 */
	public int getLeftType() {
		return leftType;
	}
	/**
	 * @param leftType the leftType to set
	 */
	public void setLeftType(int leftType) {
		this.leftType = leftType;
	}
	/**
	 * @return the rightType
	 */
	public int getRightType() {
		return rightType;
	}
	/**
	 * @param rightType the rightType to set
	 */
	public void setRightType(int rightType) {
		this.rightType = rightType;
	}
	public int getNo() {
		return no;
	}
	public HeroNode(int no, String name) {
		super();
		this.no = no;
		this.name = name;
	}
	/**
	 * @param no the no to set
	 */
	public void setNo(int no) {
		this.no = no;
	}
	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}
	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}
	/**
	 * @return the left
	 */
	public HeroNode getLeft() {
		return left;
	}
	/**
	 * @param left the left to set
	 */
	public void setLeft(HeroNode left) {
		this.left = left;
	}
	/**
	 * @return the right
	 */
	public HeroNode getRight() {
		return right;
	}
	/**
	 * @param right the right to set
	 */
	public void setRight(HeroNode right) {
		this.right = right;
	}
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "HeroNode [no=" + no + ", name=" + name + "]";
	}	
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值