中序线索二叉树Java实现

/**
 * 线索树结点类
 * @author liangxiamoyi
 *
 */
public class ThreadNode {
	/**
	 * 1标识左节点为前驱结点,0标识左节点为左子节点
	 */
	protected int lThread;
	/**
	 * 1标识右节点为后继结点,0标识右节点为右子节点
	 */
	protected int rThread;
	/**
	 * 左节点
	 */
	protected ThreadNode left;
	/**
	 * 右节点
	 */
	protected ThreadNode right;
	/**
	 * 数据
	 */
	protected char data;
	/**
	 * 构造函数
	 * @param item 数据值
	 */
	public ThreadNode(char item){
		this.data=item;
		this.lThread=this.rThread=0;
		this.left=this.right=null;
	}
}

import java.util.Scanner;

/**
 * 中序线索二叉树
 * @author liangxiamoyi
 *
 */
public class ThreadInTree {
	/**
	 * 根节点
	 */
	private ThreadNode root;
	/**
	 * 终止字符
	 */
	private char stop;
	/**
	 * 中序二叉树的线索化,指向上次遍历的结点
	 */
	private ThreadNode pre;
	/**
	 * 构造方法
	 * @param t 根节点
	 */
	public ThreadInTree(ThreadNode t){
		this.root=t;
		this.pre=null;
	}
	/**
	 * 返回以结点t为根节点的中序线索二叉树的中根序列的第一个结点
	 * @param t 根节点
	 * @return 结点
	 */
	public ThreadNode firstInOrder(ThreadNode t){
		if(t==null){
			return null;
		}
		ThreadNode q=t;
		while(q.lThread==0){
			q=q.left;
		}
		return q;
	}
	/**
	 * 返回以结点t为根节点的中序线索二叉树的中根序列的最后一个结点
	 * @param t 根节点
	 * @return 结点
	 */
	public ThreadNode lastInOrder(ThreadNode t){
		if(t==null){
			return null;
		}
		ThreadNode q=t;
		while(q.rThread==0){
			q=q.right;
		}
		return q;
	}
	/**
	 * 搜索在以t为根的中序线索二叉树中p的中根前驱结点
	 * @param t 根结点
	 * @param p 结点
	 * @return 前驱结点
	 */
	public ThreadNode preInOrder(ThreadNode t,ThreadNode p){
		if(t==null||p==null){
			return null;
		}
		ThreadNode q;
		if(p==firstInOrder(t))return null;
		if(p.lThread==1)return p.left;
		return lastInOrder(p.left);
	}
	/**
	 * 搜索在以t为根的中序线索二叉树中p的中根后继结点
	 * @param t 根结点
	 * @param p 结点
	 * @return 后继结点
	 */
	public ThreadNode postInOrder(ThreadNode t,ThreadNode p){
		if(t==null||p==null)return null;
		ThreadNode q;
		if(p==lastInOrder(t))return null;
		if(p.rThread==1)return p.right;
		return firstInOrder(p.right);
	}
	/**
	 * 中根遍历以t为根的中序线索二叉树
	 * @param t 根结点
	 */
	public void inOrder(ThreadNode t){
		if(t==null)return;
		ThreadNode q;
		for(q=firstInOrder(t);q!=null;q=postInOrder(t, q))
			System.out.print(q.data+" ");
	}
	/**
	 * 插入结点p作为结点s的右子节点
	 * @param p 插入的结点
	 * @param s
	 */
	public void insertRight(ThreadNode p,ThreadNode s){
		if(s==null||p==null)return;
		p.right=s.right;
		p.rThread=s.rThread;
		p.left=s;
		p.lThread=1;
		if(s.rThread==0){
			ThreadNode q=s.right;
			q=firstInOrder(q);//令q为s的右子树的最左结点
			q.left=p;//令q的前驱指针指向p
		}
		s.right=p;
		s.rThread=0;	
	}
	/**
	 * 插入结点p作为结点s的左子节点
	 * @param p 插入的结点
	 * @param s
	 */
	public void insertLeft(ThreadNode p,ThreadNode s){
		if(s==null||p==null)return;
		p.left=s.left;
		p.lThread=s.lThread;
		p.right=s;
		p.rThread=1;
		if(s.lThread==1&&s.left!=null){
			s.left.right=p;
		}
		if(s.lThread==0){
			lastInOrder(s.left).right=p;//令p的左子树的最右结点的后继指针指向p
		}
		s.left=p;
		s.lThread=0;	
	}
	/**
	 * 删除结点s的右子节点p
	 * @param p
	 * @param s
	 */
	public void deleteRight(ThreadNode p,ThreadNode s){
		if(s==null||p==null)return;
		if(p.lThread==1&&p.rThread==1){
			s.right=p.right;
			s.rThread=1;
		}
		if(p.lThread==1&&p.rThread==0){
			ThreadNode temp=firstInOrder(p.right);
			s.right=p.right;
			temp.left=s;
		}
		if(p.lThread==0&&p.rThread==1){
			ThreadNode temp=lastInOrder(p.left);
			s.right=p.left;
			temp.right=p.right;
		}
		if(p.lThread==0&&p.rThread==0){
			ThreadNode temp1=firstInOrder(p.right);
			ThreadNode temp=lastInOrder(p.left);
			temp.right=p.right;
			temp.rThread=0;
			s.right=p.left;
			temp1.left=temp;
		}
	}
	/**
	 * 删除结点s的左子节点p
	 * @param p
	 * @param s
	 */
	public void deleteLeft(ThreadNode p,ThreadNode s){
		if(s==null||p==null)return;
		if(p.lThread==1&&p.rThread==1){
			s.left=p.left;
			s.lThread=1;
		}
		if(p.lThread==0&&p.rThread==1){
			ThreadNode temp=lastInOrder(p.left);
			s.left=p.left;
			temp.right=s;
		}
		if(p.lThread==1&&p.rThread==0){
			ThreadNode temp=firstInOrder(p.right);
			s.left=p.right;
			temp.left=p.left;
		}
		if(p.lThread==0&&p.rThread==0){
			ThreadNode temp1=lastInOrder(p.left);
			ThreadNode temp=firstInOrder(p.right);
			temp1.right=p.right;
			temp1.rThread=0;
			s.left=p.left;
			temp.left=temp1;
		}
	}
	/**
	 * 建立以root为根节点的中序线索二叉树
	 * @param stop 输入终止符
	 */
	public void createThreadInTree(char stop){
		this.stop=stop;
		this.root=create();
		ThreadInTree(this.root);
	}
	/**
	 * 建立以root为根结点的尚未线索化的二叉树
	 * @return 根节点
	 */
	public ThreadNode create(){
		 ThreadNode t,l,r;
		char item;
		Scanner sc=new Scanner(System.in);
		item=sc.next().charAt(0);
		if(item==stop){
			t=null;
			return t;
		}
		else{
			t=new ThreadNode(item);
			l=create();
			t.left=l;
			r=create();
			t.right=r;
			return t;
		}
	}
	/**
	 * 将以root为根节点的二叉树化为中序线索二叉树
	 */
	public void ThreadInTree(ThreadNode t){
		if(t==null)return;
		ThreadInTree(t.left);
		if(t.left==null){//左子树为空,设置前驱结点
			t.lThread=1;
			if(pre!=null){
				t.left=pre;
			}
		}
		if(t.right==null){//先标记,在下一次遍历设置后继结点
			t.rThread=1;
		}
		if(pre!=null&&pre.rThread==1){//为上次被标记的结点设置后继结点
			pre.right=t;
		}
		pre=t;//记录当前结点
		ThreadInTree(t.right);//右子树
	}
	/**
	 * 获得中序遍历的第一个结点
	 * @return
	 */
	public ThreadNode getFirst(){
		return firstInOrder(root);
	}
	/**
	 * 获得中序遍历的最后一个结点
	 * @return
	 */
	public ThreadNode getLast(){
		return lastInOrder(root);
	}
	/**
	 * 搜索在以root为根的树中数据为item的结点
	 * @param root
	 * @param item
	 * @return
	 */
	public ThreadNode find(ThreadNode root,char item){
		if(root==null)return null;
		ThreadNode q;
		for(q=firstInOrder(root);q!=null;q=postInOrder(root, q)){
			if(q.data==item){
				return q;
			}
		}
		return null;
	}
	
	public static void main(String[] args){
		ThreadInTree tit=new ThreadInTree(null);
		tit.createThreadInTree('z');
		System.out.println("中序遍历的第一个节点为:");
		System.out.println(tit.getFirst().data);
		System.out.println("中序遍历的最后一个结点:");
		System.out.println(tit.getLast().data);
		System.out.println("中序遍历为:");
		tit.inOrder(tit.root);
		System.out.println("");
		ThreadNode a=new ThreadNode('g');
		ThreadNode c=new ThreadNode('h');
		ThreadNode b=tit.find(tit.root, 'c');
		System.out.println("在c插入左子节点g后中序遍历:");
		tit.insertLeft(a,b);
		tit.inOrder(tit.root);
		System.out.println("");
		System.out.println("在c插入右子节点h后中序遍历:");
		tit.insertRight(c,b);
		tit.inOrder(tit.root);
		System.out.println("");
		tit.deleteLeft(tit.find(tit.root, 'e'), tit.find(tit.root, 'd'));
		System.out.println("d删除左子节点e后中序遍历:");
		tit.inOrder(tit.root);
		System.out.println("");
		tit.deleteRight(tit.find(tit.root, 'h'), tit.find(tit.root, 'c'));
		System.out.println("c删除右子节点h后中序遍历:");
		tit.inOrder(tit.root);
	}
}

测试结果:


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值