/**
* 线索树结点类
* @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);
}
}
测试结果: