线索二叉树(中序) Java实现

代码所示为下图二叉树

中序遍历:CBDAEF

C,D,F有两个空指针域,E有一个


步骤如下:

1.创建二叉树

2.创建头结点

3.中序遍历线索化

4.中序遍历此线索二叉树(非递归方式)

public class ThreadedBinaryTree {
	
	private static String [] array = {"A","B","C","","","D","","","E","","F","",""};
	private static int arrayIndex = 0;
	
	/**
	 * 全局node,始终指向刚刚访问过的结点
	 */
	private static ThreadedBinaryNode preNode;
	
	/**
	 * 1.参考创建二叉树,前序遍历输入
	 */
	public static ThreadedBinaryNode createThreadedBinaryTree(){
		String data = "";
		if(arrayIndex<array.length){
			data = array[arrayIndex];
			
			arrayIndex++;
		}
		
		ThreadedBinaryNode node = null;
		
//		data为空表示没有这个孩子
		if(data==null||data.equals("")){
			return node;
		}else{
			node = new ThreadedBinaryNode(data);
			node.setLchild(createThreadedBinaryTree());
			node.setRchild(createThreadedBinaryTree());
			
			node.setLtag(PointerTag.LINK);
			node.setRtag(PointerTag.LINK);
			
			return node;
		}
	}
	
	/**
	 * 2.创建头结点,左孩子指向根节点
	 * @param rootNode
	 */
	public static ThreadedBinaryNode createHeadNode(ThreadedBinaryNode rootNode){
		ThreadedBinaryNode headNode = new ThreadedBinaryNode();
		
		headNode.setLtag(PointerTag.LINK);
		headNode.setRtag(PointerTag.THREAD);
		
//		右孩子先指向自己,如果根节点不为null,指向中序遍历的最后一个结点,为null不用变
		headNode.setRchild(headNode);
		
		if(rootNode != null){
//			根结点不为null,头结点的左孩子指向根结点
			headNode.setLchild(rootNode);
			
			preNode = headNode;
			
//			开始中序遍历根结点
			inOrderTraverse(rootNode);
			
//			中序遍历的最后一个结点的后继指向头结点
			preNode.setRtag(PointerTag.THREAD);
			preNode.setRchild(headNode);
			
//			头结点的右孩子指向最后一个结点
			headNode.setRchild(preNode);
			
		}else{
//			根节点为null 左孩子指向自己
			headNode.setLchild(headNode);
		}
		
		return headNode;
	}
	
	/**
	 * 3.中序遍历线索化
	 */
	public static void inOrderTraverse(ThreadedBinaryNode node){
		if(node != null){
//			递归左孩子线索化
			inOrderTraverse(node.getLchild());
			
//			结点处理
			if(null == node.getLchild()){
//				如果左孩子为空,设置tag为线索 THREAD,并把lchild指向刚刚访问的结点
				node.setLtag(PointerTag.THREAD);
				node.setLchild(preNode);
			}
			
			if(null == preNode.getRchild()){
//				如果preNode的右孩子为空,设置tag为线索THREAD
				preNode.setRtag(PointerTag.THREAD);
				preNode.setRchild(node);
			}
			
//			此处和前后两个递归的顺序不能改变,和结点处理同属一个级别
			preNode = node;
//			System.out.print(node.getData());
			
//			递归右孩子线索化
			inOrderTraverse(node.getRchild());
			
		}
	}
	
	/**
	 * 4.中序遍历 非递归方式
	 * @param headNode
	 */
	public static void inOrderTraverseNotRecursion(ThreadedBinaryNode headNode){
		ThreadedBinaryNode node = headNode.getLchild();
		
		while(headNode != node){
			
//			最左
			while(node.getLtag() == PointerTag.LINK){
				node = node.getLchild();
			}
			
			System.out.print(node.getData());
			
//			根
			while(node.getRtag() == PointerTag.THREAD && node.getRchild() !=headNode){
				node = node.getRchild();
				
				System.out.print(node.getData());
			}
			
//			右,不能打印是因为该子树下可能还存在最左
			node = node.getRchild();
		}
	}
	
	
	
	public static void main(String[] args) {
//		创建二叉树,约定前序输入
		ThreadedBinaryNode rootNode = createThreadedBinaryTree();
//		创建头结点,并中序遍历线索化
		ThreadedBinaryNode headNode = createHeadNode(rootNode);
//		中序遍历 非递归方式输出
		inOrderTraverseNotRecursion(headNode);
	}

}

class ThreadedBinaryNode{
	private String data;
	
	private ThreadedBinaryNode lchild;
	private ThreadedBinaryNode rchild;
	
	private PointerTag ltag;
	private PointerTag rtag;
	
	
	public String getData() {
		return data;
	}
	public void setData(String data) {
		this.data = data;
	}
	public ThreadedBinaryNode getLchild() {
		return lchild;
	}
	public void setLchild(ThreadedBinaryNode lchild) {
		this.lchild = lchild;
	}
	public ThreadedBinaryNode getRchild() {
		return rchild;
	}
	public void setRchild(ThreadedBinaryNode rchild) {
		this.rchild = rchild;
	}
	public PointerTag getLtag() {
		return ltag;
	}
	public void setLtag(PointerTag ltag) {
		this.ltag = ltag;
	}
	public PointerTag getRtag() {
		return rtag;
	}
	public void setRtag(PointerTag rtag) {
		this.rtag = rtag;
	}
	
	
	public ThreadedBinaryNode(String data) {
		super();
		this.data = data;
	}
	public ThreadedBinaryNode() {
		super();
	}
	@Override
	public String toString() {
		return "ThreadedBinaryNode [data=" + data + ", ltag=" + ltag
				+ ", rtag=" + rtag + "]";
	}
	
	
	
}

/**
 * LINK :表示指向左右孩子的指针
 * THREAD:表示指向前驱后继的线索
 * @author cmdsm
 *
 */
enum PointerTag{
	LINK , THREAD
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值