数据结构7—线索二叉树 (java)

来源:互联网 发布:淘宝帐号查询 编辑:程序博客网 时间:2024/06/03 19:02

二叉链表作为存储结构时只能找到结点的左、右孩子的信息,而不能直接得到结点的任一序列的前驱和后继信息,这种信息只有在遍历的动态过程中才能得到。

为保存前驱和后继信息,在每个结点的指针域增加两个区域,分别标识其前驱和后继,并增加两个标志区域。
这里写图片描述

只有中序遍历才可以对其进行线索化!!
把树的结构遍历的时候看一下哪些地方有空余,会发现中序刚好每个结点间都有

    -

结点类

public class BiNode<T> {    private T data;    private BiNode<T>lChild;    private BiNode<T> rChild;    private int lTag;    private int rTag;    public int getlTag() {        return lTag;    }    public void setlTag(int lTag) {        this.lTag = lTag;    }    public int getrTag() {        return rTag;    }    public void setrTag(int rTag) {        this.rTag = rTag;    }    BiNode( T Data){        this.data=Data;    }    public T getData() {        return data;    }    public void setData(T data) {        this.data = data;    }    public BiNode<T> getlChild() {        return lChild;    }    public void setlChild(BiNode<T> lChild) {        this.lChild = lChild;    }    public BiNode<T> getrChild() {        return rChild;    }    public void setrChild(BiNode<T> rChild) {        this.rChild = rChild;    }   }

前序遍历生成一颗树

    public String[] str;    int count=0;    /*前序遍历生成一颗树*/       public BiNode<T> CreateBiTree(){        BiNode<T> bNode =null;        if(count >= str.length || str[count++].equals("#")){            bNode = null;        }        else{            bNode = new BiNode<T>((T)str[count-1]);            bNode.setlChild(CreateBiTree());            bNode.setrChild(CreateBiTree());            bNode.setlTag(0);//先把所有子树标识为都有孩子            bNode.setrTag(0);        }        return bNode;    }

线索化

    //全局变量,始终指向刚访问过的结点    BiNode<T> pre=null;    /*初始化pre_建立头指针,左孩子指向第一个结点,右孩子为线索,树的第一个访问或最后一个访问结点指向他 */    public BiNode<T> InOrderThreading(BiNode<T> btree){        BiNode<T> p = new BiNode<T>(null);//头结点        p.setlTag(0);        p.setrTag(1);        p.setrChild(p);        if(btree==null){//二叉树为空,则回指            p.setlChild(p);        }else{            p.setlChild(btree);//头结点加到树上            pre=p;            InThreading(btree);//中序遍历线索化            pre.setrChild(p);//最后一个结点线索化            pre.setrTag(1);            p.setrChild(pre);                               }        return  p;    }

中序遍历线索化

    /*中序遍历线索化*/    public void InThreading(BiNode<T> root){        if(root!=null){            InThreading(root.getlChild());//左孩子线索化            //结点处理            if(root.getlChild()==null){//该结点没有左孩子,设置标识为1,并把lchild指向前驱(刚刚访问的结点)                root.setlTag(1);                root.setlChild(pre);            }            if(pre!=null&&pre.getrChild()==null){//此时不能知道p的后继是什么,只能知道刚才的结点pre的后继为btree                pre.setrTag(1);                pre.setrChild(root);            }            pre=root;            InThreading(root.getrChild());//右孩子线索化        }    }   

->中序遍历非递归

    /*中序非递归*/    public static void OrderTraverse(BiNode<Integer> root){        BiNode<Integer> p;        p=root.getlChild();        while(p!=root){            while(p.getlTag()==0){                p = p.getlChild();            }            System.out.print(p.getData());            while(p.getrTag()==1&&p.getrChild()!=root){                p=p.getrChild();                System.out.print(p.getData());            }            p = p.getrChild();        }    }

测试->

    public static  void main(String[] args) {          Scanner cin = new Scanner(System.in);          while (cin.hasNext()) {             String s = cin.nextLine();             String[] str = s.split(",");             BitThrTree<Integer> tree = new BitThrTree<Integer>();             tree.str=str;             BiNode<Integer> root = tree.CreateBiTree();             OrderTraverse(tree.InOrderThreading(root));          }    }

结果

输入:A,B,D,G,#,#,H,#,#,#,C,E,#,T,#,#,F,#,#输出结果:GDHBAETCF(中序遍历结果)

图的结构见
http://blog.csdn.net/luotuomianyang/article/details/50933465

程序中有一些定义不规范的地方比如:定义变量的时候如l和1,i要分清,l一般为L,LChild~后序在改进

0 0
原创粉丝点击