中序线索化二叉树

1) n 个结点的二叉链表中含有 n+1  【 公式 2n- (n-1)= n+1】 空指针域。利用二叉链表中的空指针域,存放指 某种遍历次序 下的前驱和后继结 点的指针( 这种附加的指针称为 " 线索 "

 

2) 种加上了线索的二叉链表称为 线索链表 ,相应的二叉树称为 线索二叉树 (Threaded BinaryTree ) 。根据线索性质的不同,线索二叉树可分为 前序线索二叉树、中序线索二叉树 后序线索二叉树
3) 一个结点的前一 个结点 ,称为 前驱 结点
4) 一个结点 的后一 个结点 ,称为 后继 结点

         中序遍历的结果:{8, 3, 10, 1, 14, 6}

当线索化二叉树后,Node节点的 属性 left right

1)left 指向的是左子树,也可能是指向的前驱节点. 比如 ① 节点 left 指向的左子树, 而 ⑩ 节点的 left 指向的就是前驱节点.

2)right指向的是右子树,也可能是指向后继节点,比如 ① right 指向的是右子树,而⑩ 节点的right 指向的是后继节点.

package com.zhen;


public class ClueBinary {

	public static void main(String[] args) {
		//手动创建
		Node root = new Node(1, "1");
		Node node2 = new Node(3, "3");
		Node node3 = new Node(6, "6");
		Node node4 = new Node(8, "8");
		Node node5 = new Node(10, "10");
		Node node6 = new Node(14, "14");
		root.setLeft(node2);
		root.setRight(node3);
		node2.setLeft(node4);
		node2.setRight(node5);
		node3.setLeft(node6);
		//测试
		ClueTree clueTree = new ClueTree();
		clueTree.infixNode(root);
		
		Node left5 = node5.getLeft();
		Node right5 = node5.getRight();
		System.out.println("10的前驱节点为:"+left5);
		System.out.println("10的后继节点为:"+right5);
		
		System.out.println("线索化遍历:");
		clueTree.setRoot(root);
		clueTree.infixList();
	}

}

//线索二叉树
class ClueTree{
	//根节点
	private Node root;
	
	//用于保留线索化的前一个节点
	private Node pre=null;

	public void setRoot(Node root) {
		this.root = root;
	}
	
	
	//中序线索化
	public void infixNode(Node node) {
		if (node==null) {
			return;
		}
		
		//1.线索化左子树
		infixNode(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.线索化右子树
		infixNode(node.getRight());
	}
	
	
	//遍历中序线索二叉树
	public void infixList() {
		//存储当前遍历的节点从root开始
		Node node=root;
		while (node != null) {
			//循环去找leftType=1的节点,因为该节点为有效节点
			
			//跳过为0的
			while(node.getLeftType()==0) {
				node=node.getLeft();
			}
			
			//打印当前节点
			System.out.println(node);
			while(node.getRightType()==1) {
				//获取后继节点
				node = node.getRight();
				System.out.println(node);
			}
			//不等于1就替换
			node=node.getRight();
		}
	}
}

//节点
class Node{
	private int no;
	private String name;
	private Node left;
	private Node right;
	
	//如果leftType=0指向左子树,leftType=1指向前驱节点
	private int leftType;
	//如果rightType=0指向右子树,rightType=1指向后继节点
	private int rightType;
	
	
	public Node(int no, String name) {
		super();
		this.no = no;
		this.name = name;
	}
	public int getNo() {
		return no;
	}
	public void setNo(int no) {
		this.no = no;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Node getLeft() {
		return left;
	}
	public void setLeft(Node left) {
		this.left = left;
	}
	public Node getRight() {
		return right;
	}
	public void setRight(Node right) {
		this.right = right;
	}
	
	public int getLeftType() {
		return leftType;
	}
	public void setLeftType(int leftType) {
		this.leftType = leftType;
	}
	public int getRightType() {
		return rightType;
	}
	public void setRightType(int rightType) {
		this.rightType = rightType;
	}
	@Override
	public String toString() {
		return "Node [no=" + no + ", name=" + name + "]";
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

1while(true){learn}

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值