java线索二叉树

2021/9/28 20:12:28

本文主要是介绍java线索二叉树,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

线索二叉树是利用叶子结点的左右子树结点指向自己的前驱后继

利用浪费的空间让树更加效率

先创建二叉树结点:

public class node {

   private int no;
   private String name;
   private node Left;
   private node Right;
    /**
     * NoLeft和NoRight表示一个结点的左右节点是否有结点
     * 如果有则表示1 没有则为0
     */
   private int NoLeft;
   private int NoRight;

    public node(int no, String name) {
        this.no = no;
        this.name = name;
    }

    /**
     * 删除结点
     * @param no
     */
    public void DelNode(int no){
        /*
        判断左子树是否为空,并且左子树的No是否等于要删除的no如果相等则把左子树置为空 删掉左子树。
        如果不相等那就在下面递归
         */
        if(this.Left!=null&&this.Left.getNo()==no){
            this.Left=null;
            return;
        }
        /*
        判断右子树和左子树同理
         */
        if(this.Right!=null&&this.Right.getNo()==no){
            this.Right=null;
            return;
        }
        /*
        判断子树是否为空 继续递归下 直到直到叶子结点
         */
        if(this.Left!=null){
            this.Left.DelNode(no);
        }
        if(this.Right!=null){
            this.Right.DelNode(no);
        }
    }
    /**
     * 中序遍历
     */
    public void MidSelect(){
        /*
        判断结点子树是否为空 同时也是递归的终止条件
         */
        if(this.Left!=null) this.Left.MidSelect();//向左递归
        System.out.println(this);//输出此结点的数据
        if(this.Right!=null) this.Right.MidSelect();//向右递归
    }
    /**
     * 根据编号中序查找
     */
    public node MidFound(int no){
        /*
        设计辅助结点,用来接收返回值
        也是用来返回的值
         */
        node temp=null;
        /*
        如果左子树有结点则递归左子树接收返回值
         */
        if(this.Left!=null){
            temp=this.Left.MidFound(no);
        }
        /*
        用来递归左子树的结点 如果没找到则temp为null
         */
        if(temp!=null) return temp;
        /*
        判断该结点是否为要查找的值结点
         */
        if(this.getNo()==no){
            return this;
        }
        if(this.Right!=null){
            temp=this.Right.MidFound(no);
        }
        /*
        用来递归右子树的结点 如果没找到则temp为null
         */
        return temp;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public node getLeft() {
        return Left;
    }

    public void setLeft(node left) {
        Left = left;
    }

    public node getRight() {
        return Right;
    }

    public void setRight(node right) {
        Right = right;
    }

    public int getNoLeft() {
        return NoLeft;
    }

    public void setNoLeft(int noLeft) {
        NoLeft = noLeft;
    }

    public int getNoRight() {
        return NoRight;
    }

    public void setNoRight(int noRight) {
        NoRight = noRight;
    }

    @Override
    public String toString() {
        return "node{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }
}

创建一个线索二叉树的建立:

public class BinaryTree {
    /**
     * root为根结点
     */
    private node root;
    /**
     * pre是用来指向前驱的结点的继辅助指针
     */
    private node pre;

    public void setRoot(node root) {
        this.root = root;
    }

    /**
     * 普通二叉树转线索二叉树
     */
    /**
     * 重载方法 方便试用
     */
    public void ClueNode(){
        this.ClueNode(this.root);
    }

    public void ClueNode(node n){
        if(n==null) return;
        /*
        中序转化 先线索化左子树一直递归到左子树
         */
        ClueNode(n.getLeft());
        //找到叶子结点没有前驱后继都是Null
        /*
        找到叶子结点后他的前驱肯定是空的 那么pre也是null直接赋值
        并且设置为有结点状态
        中序遍历的最左边的叶子前驱是没有东西的
        其他结点同理
         */
        if(n.getLeft()==null){
            n.setLeft(pre);
            n.setNoLeft(1);
        }
        //如果该结点pre不为空那说明该结点的前驱有了
        //那就可以赋值后继
        /**
         * 那就可以吧此结点设置为pre来当下个结点的前驱也就是此结点的后继
         * 如果pre不为空那表示已经有结点了
         * 那就把pre设置为此结点来表示下个结点的前驱
         * 有点类似于链表的辅助temp遍历链表
         */
        if(pre!=null&&pre.getRight()==null){
            pre.setRight(n);
            pre.setNoRight(1);
        }
        //迭代处理下一个结点
        pre=n;
        /*
        左子树处理完然后继续递归右子树
         */
        ClueNode(n.getRight());
    }
    /**
     * 遍历线索化二叉树
     */
    public void ClueList(){
        //创建临时结点用来迭代每个结点
        node temp = this.root;
        while(temp!=null){
            //中序查询先从左子树查
            //循环从根结点出发根结点的NoLeft是等于0的
            //而最左子树的结点的NoLeft是等于1的
            //也就是说到最左子树的时候停下并且打印
            while(temp.getNoLeft()==0){
                temp=temp.getLeft();
            }
            System.out.println(temp);
            //现在temp是等于最左边的子树然后寻找后继就可以了
            //叶子结点的NoRight如果等于1那就表示有后继
            //如果一个结点拥有左右子树的话那这个结点的前驱后继是等于0的
            //也就是从这个等于0的结点进行
            /*
            //继续循环找
            temp=temp.getRight();
             */
            while(temp.getNoRight()==1){
                temp=temp.getRight();
                System.out.println(temp);
            }
            //继续循环找
            temp=temp.getRight();
        }
    }
}



这篇关于java线索二叉树的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程