二叉查找树

package Tree;
/*
    二叉排序树:父节点大于左子节点,并且父节点小于右子节点的二叉树


 */
public class BinarySortTree {
    //根节点
    Node root;

    public BinarySortTree() {
    }

    public BinarySortTree(Node root) {
        this.root = root;
    }

    public BinarySortTree(int num) {
       this(new Node(num));
    }

    public void add(Node node){
        if(this.root==null)
            root=node;
        else
            this.root.add(node);
    }

    public void add(int num){
        if(this.root==null)
            root=new Node(num);
        else
            this.root.add(new Node(num));
    }

    //前序遍历
    public void preOrder(){
        if(root==null)
            System.out.println("空树,无数据");
        else
            root.preOrder();
    }
    //删除树中的一个节点 不能删除根节点,因为删除节点大体上分两种情况,待删除节点有两个子节点和待删除节点的子节点数量没有两个
    //如果删除根节点还需要另外一种方法
    public void delete(Node node) {
        //如果root为空 那么直接结束
        if(root==null)
            return;
        Node target=root.searchNode(node);
        if(target==null){
            System.out.println("待删除的节点不存在");
            return;
        }
        //待删除节点有两个叶子节点
        if(target.left!=null&&target.right!=null){
            //待删除节点有两个子节点
            System.out.println("两个子节点");
            System.out.println(target.left);
            //默认用待删除子节点的左子树的最右子节点来代替待删除节点
            //找到最右子节点
            Node node1=target.left.searchRight();
            //将最右右子节点的值赋值给待删除节点
            target.value=node1.value;
            //找到最右子节点的父节点
            //左子树的最右字节点是待删除子节点的左子节点,直接将左子节点置空
            if(node1.value==target.left.value){
                target.left=null;
            }else{
                //如果不是待删除子节点的左子节点,那么找到最右子节点的
                Node node2 = target.searchFather(node1);
                node2.right=null;
            }
        }
        //待删除节点有一个或者没有叶子节点
        else {
            Node father  = root.searchFather(node);
            //定位待删除的节点,是已经寻找到的父节点的子节点
            if(father.right==null){
                target=father.left;
            }else if(father.left==null)
                target=father.right;
            else{
                if(father.left.value== node.value)
                    target=father.left;
                else
                    target=father.right;
            }
            //判断删除的是哪一种情况
            if(target.left==null&&target.right==null) {
                System.out.println("删除叶子节点");
                System.out.println(father);
                System.out.println(target);
                //如果待删除的节点是一个叶子节点,那么直接将father的对应的待删除的子节点置空
                if(father.left!=null){
                    if(father.left.value==target.value)
                        father.left=null;
                }else{
                    father.right=null;
//                    System.out.println("撒谎从");
                }
                return ;
            }
            //待删除的节点只有一个子节点

        }



    }

    //先写一个内部节点类
     public static class Node{
        int value;
        Node right;
        Node left;

        public Node() {
        }

        public Node(int value) {
            this.value = value;
        }

        void add(Node node){
            if(node.value>this.value){
                if(this.right==null)
                    this.right=node;
                else
                    this.right.add(node);
            }else{
                if(this.left==null)
                    this.left=node;
                else
                    this.left.add(node);
            }
        }
        public void preOrder(){
            if(this!=null){
                System.out.println(this);
                if(this.left!=null)
                    this.left.preOrder();
                if(this.right!=null)
                    this.right.preOrder();
            }
        }
        public Node searchNode(Node node){
            if(this.value==node.value)
                return this;
            else if(this.value>node.value){
                if(this.left!=null)
                    return this.left.searchNode(node);
            }else if(this.right!=null)
                return this.right.searchNode(node);
            return null;
        }

        //删除一个节点

//        public void delete(Node node){
//            if(this.value==node.value){
//        WDF  不可以直接置空 下一个
//                if(this.left==null&&this.right==null) this = null;
//            }
//        }
        //既然不可以通过想要删除的对象直接置空,那就通过父节点进行置空,所以首先要找到父节点
        public Node searchFather(Node node){
            if(this.value>node.value){
//                System.out.println("left");
                if(this.left!=null){
                    if(this.left.value== node.value)
                        return this;
                    return this.left.searchFather(node);
                }

            }else{
//                System.out.println("right");
                if(this.right!=null){
                    if(this.right.value== node.value)
                        return this;
                    return this.right.searchFather(node);
                }

            }
            return null;
        }

        //寻找到一个节点左子树中的最右节点的父节点的值
        public Node searchRight(){
            System.out.println("right");
            Node temp=this;
           while(temp.right!=null){
               temp=temp.right;
           }
           return temp;
        }

        @Override
        public String toString() {
            return "Node{" +
                    "value=" + value +
                    '}';
        }

    }

    public static void main(String[] args) {
        int nums[]={5,8,1,12,64,23,44,5,8,9};
        BinarySortTree binarySortTree = new BinarySortTree();
        for(int i : nums){
            binarySortTree.add(i);
        }
        binarySortTree.preOrder();
        System.out.println("**************");
        System.out.println(binarySortTree.root.searchFather(new Node(44)));
        System.out.println(binarySortTree.root.searchRight());
        binarySortTree.delete(new Node(25));
        System.out.println("************");
        binarySortTree.preOrder();
//        System.out.println(binarySortTree.root.searchNode(new Node(44)));
//        System.out.println(binarySortTree.root.searchFather(new Node(5)));
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值