中序线索二叉树Java实现

来源:互联网 发布:西科在线网络教育 编辑:程序博客网 时间:2024/05/17 01:56
/** * 线索树结点类 * @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 0
原创粉丝点击