JAVA二叉查找树(搜索树)

JAVA二叉查找树(搜索树)

自己通过java实现的二叉查找树,完整代码,有需求自取即可
包含,添加节点,删除节点(最复杂),查找节点三个主要的方法,有兴趣可以看一下

这里泛型Key继承了Comparable类用于比较键值大小

public class BinaryTree<Key extends Comparable<Key>,Value> {
    private Node root;//根节点
    private int N;//节点数

    private class Node {
        Key key;
        Value value;
        Node left;
        Node right;

        public Node() {
        }

        public Node(Key key, Value value, Node left, Node right) {
            this.key = key;
            this.value = value;
            this.left = left;
            this.right = right;
        }
    }

    public BinaryTree() {
        root = new Node(null, null, null, null);//初始化根节点
        N = 0;//初始化节点数量
    }

    public void put(Key k, Value v) {
        Node n = root;
        //根节点赋值
        if (n.value == null) {
            n.key=k;
            n.value=v;
            N++;
            return;
        }
        while (true) {
            //key值相等,直接替换
            if (k.compareTo(n.key) == 0) {
                n.value = v;
                return;
            } else if (k.compareTo(n.key) > 0) {
                //找右节点
                if (n.right!=null)
                n = n.right;
                else if (n.right==null){
                 n.right=new Node(k,v,null,null);
                 N++;
                 return;
                }
            }
            //找左节点
            else if(k.compareTo(n.key) < 0){
                if (n.left!=null)
                    n = n.right;
                else if (n.left==null){
                    n.left=new Node(k,v,null,null);
                    N++;
                    return;
                }
            }
        }
    }



    public Value get(Key k) {
        Node n = root;
        while (true){
            if (n==null){
                return null;
            }
            if (n.key.compareTo(k)==0){
                return n.value;
            }
            else if (n.key.compareTo(k)>0){
                n=n.left;
            }
            else
                n=n.right;
        }
    }

    public  int getSize(){
        return N;
    }

    public void delete(Key k){
        Node n=root;
        Node target=null;
        Node target_father=null;
        boolean target_is_left=true;
        Node min_right=null;//右子树上最小的节点
        Node min_right_father;//右子树上最小节点的父节点
        if (root.key==null){
            return;
        }
        //找到要删除的节点,及其父节点
        while(n!=null){
            if (k.compareTo(n.key)==0){
              target=n;
              break;
            }
            if (k.compareTo(n.key)>0){
                target_father=n;
                target_is_left=false;
                n=n.right;

            }
            else if (k.compareTo(n.key)<0){
                target_father=n;
                target_is_left=true;
                n=n.left;
            }
        }
        //如果没找到就提前结束
        if (n==null){
            return;
        }
        //如果找到了,target即指向要删除的节点

        //1、如果节点为叶子节点
        if (target.left==null&&target.right==null){
            //如果删除节点的父节点为空,即删除节点是根节点
            if (target_father==null){
                target.key=null;
                target.value=null;
                N--;
                return;
            }
            //如果删除节点存在父节点
            else if (target_father!=null){
                //如果删除节点是其父节点的左节点
                if (target_is_left){
                    target_father.left=null;
                    N--;
                    return;
                }
                //如果删除节点是其父节点的右节点
                else {
                    target_father.right=null;
                    N--;
                    return;
                }
            }
        }

        //2、如果删除节点只有左子树
        if (target.right==null&&target.left!=null){
            //当删除节点是根节点
            if (target_father==null) {
                root=root.left;
                N--;
                return;
            }
            if (target_father!=null){
                //如果删除节点是其父节点左子树
                if (target_is_left){
                    target_father.left=target.left;
                    N--;
                    return;
                }
                else {
                    target_father.right=target.left;
                    N--;
                    return;
                }
            }
        }

        //3、如果删除节点只有右子树
        if (target.right!=null&&target.left==null){
            //当删除节点是根节点
            if (target_father==null) {
                root=root.right;
                N--;
                return;
            }
            if (target_father!=null){
                //如果删除节点是其父节点左子树
                if (target_is_left){
                    target_father.left=target.right;
                    N--;
                    return;
                }
                else {
                    target_father.right=target.right;
                    N--;
                    return;
                }
            }
        }

        //4、如果删除节点有左右子树
        //找到其右子树上最小的节点(该节点一定不存在左子树)
        if (target.left!=null&&target.right!=null){
            min_right=target.right;
            min_right_father=target;
            while (min_right.left!=null){
                min_right_father=min_right;
                min_right=min_right.left;
            }
            //如果删除的节点是根节点
            if (target_father==null){
                //当用于替换的节点就是目标节点的右节点,即target的右节点没有左节点
                if (min_right_father==target){
                    min_right.left=target.left;
                    root=min_right;
                    N--;
                    return;
                }
                //若不是
                else {
                    min_right_father.left=min_right.right;
                    min_right.left=target.left;
                    min_right.right=target.right;
                    root=min_right;
                    N--;
                    return;
                }
            }
            //若删除不是根节点
            else {
                //当用于替换的节点就是目标节点的右节点,即target的右节点没有左节点
                if (min_right_father==target){
                    min_right.left=target.left;
                    if (target_is_left){
                        target_father.left=min_right;
                    }
                    else {
                        target_father.right=min_right;
                    }
                    N--;
                    return;
                }
                //若不是
                else {
                    min_right_father.left=min_right.right;
                    min_right.left=target.left;
                    min_right.right=target.right;
                    if (target_is_left){
                        target_father.left=min_right;
                    }
                    else {
                        target_father.right=min_right;
                    }
                    N--;
                    return;
                }
            }
        }
    }

  //二叉树的基础遍历
    //获取二叉树前序遍历出的key值队列
    public Queue<Key> getPreQueue(){
        Queue<Key> keys = new Queue<Key>();
        preErgodic(root,keys);
        return keys;
    }

    //获取指定树中所有节点关键值,置于队列中(前序遍历)
    private void preErgodic(Node node,Queue<Key> keys){
        //如果传入节点为空,直接结束
        if (node==null){
            return;
        }
        keys.enqueue(node.key);
        if (node.left!=null){
            preErgodic(node.left,keys);
        }
        if (node.right!=null){
            preErgodic(node.right,keys);
        }
    }

    //获取二叉树中序遍历出的key值队列
    public Queue<Key> getMinQueue(){
        Queue<Key> keys = new Queue<Key>();
        midErgodic(root,keys);
        return keys;
    }

    //获取指定树中所有节点关键值,置于队列中(中序遍历)
    private void midErgodic(Node node,Queue<Key> keys){
        //如果传入节点为空,直接结束
        if (node==null){
            return;
        }
        if (node.left!=null){
            preErgodic(node.left,keys);
        }
        keys.enqueue(node.key);
        if (node.right!=null){
            preErgodic(node.right,keys);
        }
    }

    //获取二叉树后序遍历出的key值队列
    public Queue<Key> getAfterQueue(){
        Queue<Key> keys = new Queue<Key>();
        afterErgodic(root,keys);
        return keys;
    }

    //获取指定树中所有节点关键值,置于队列中(后序遍历)
    private void afterErgodic(Node node,Queue<Key> keys){
        //如果传入节点为空,直接结束
        if (node==null){
            return;
        }
        if (node.left!=null){
            preErgodic(node.left,keys);
        }
        if (node.right!=null){
            preErgodic(node.right,keys);
        }
        keys.enqueue(node.key);
    }


    //获取二叉树层序遍历出的key值队列
    public Queue<Key> getLayerQueue(){
        Queue<Key> keys = new Queue<Key>();
        layerErgodic(root,keys);
        return keys;
    }
    private void layerErgodic(Node node,Queue<Key> keys){
        Queue<Node> queue = new Queue<>();
        queue.enqueue(root);
        while (queue.getSize()!=0){
            Node n=queue.dequeue();
            keys.enqueue(n.key);
            if (n.left!=null){
                queue.enqueue(n.left);
            }
            if (n.right!=null){
                queue.enqueue(n.right);
            }
        }
    }



    //计算树的最大深度
    public int getDepth(){
        return maxDepth(root);
    }

    private int maxDepth(Node node){
        if (node==null){
            return 0;
        }
        //当前树的最大深度
        int max=0;
        //左子树的最大深度
        int maxL=0;
        //右子树最大深度
        int maxR=0;
        if (node.left!=null){
            maxL=maxDepth(node.left);
        }
        if (node.right!=null){
            maxR=maxDepth(node.right);
        }
        max=maxL>=maxR?maxL+1:maxR+1;
        return max;//返回本树最大深度
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值