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();
        }
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值