数据结构:java实现二分搜索树

1.二叉树

1.定义
二叉树是一种每个结点至多只有两个子树(左子树,右子树),并且二叉树的子树左右之分不能颠倒。
2.性质
(1)在二叉树的第i层,最多有2^(i-1)个结点;
(2)深度为k的二叉树最多有(2^k)-1个结点;
3.满二叉树
除了叶子结点外的每个结点都有左右两个子树。

2.java实现二分搜索树

1.二分搜索树特点

  • 二分搜索树是一个动态数据结构;
  • 二分搜索树也是一个二叉树;
  • 二分搜索树的每个结点的值都大于其左子树上的所有结点的值,小于其右子树上的所有结点的值;
  • 存储的元素必须有可比较性,必须实现Comparable接口,或者使用额外的比较器实现;
  • 每一颗子树也是二分搜索树;
  • 二分搜索树具有唯一的根节点,同时,在二叉树中的最底下是它的叶子结点。
  • 二分搜索树天然的具有递归特性:(1)每个结点的左子树也是二叉树;(2)每个结点的右子树也是二叉树。

2.java实现

public class BST<T extends Comparable<T>> {
    private class Node<T extends Comparable<T>>{
        T ele;
        Node left,right;//左右子树

        public Node(T ele){
            this.ele = ele;
            this.left = null;
            this.right = null;
        }
    }

    //根节点
    private Node root;
    private int size;

    public BST(){
        root = null;
        size = 0;
    }

    //获取长度
    public int getSize(){
        return size;
    }

    //判断是否为空
    public boolean isEmpty(){
        return size == 0;
    }

    //添加元素
    public void add(T ele){
        root = addEle(root,ele);
    }
    private Node addEle(Node node,T e){
        if(node == null){
            size++;
            return new Node(e);
        }
        if(node.ele.compareTo(e) > 0){
            node.left = addEle(node.left,e);
        }else if(node.ele.compareTo(e) < 0){
            node.right = addEle(node.right,e);
        }
        return node;
    }

    //判断二分搜索树是否含有指定元素
    public boolean contains(T ele){
        return containsEle(root,ele);
    }
    private boolean containsEle(Node node,T e){
        if(node == null){
            return false;
        }
        if(node.ele.compareTo(e) > 0){
             return containsEle(node.left,e);
        }else if(node.ele.compareTo(e) < 0){
             return containsEle(node.right,e);
        }else {
            return true;
        }
    }

    //二叉树遍历(前序遍历)

    /**
     * 1.当前结点
     * 2.左子树
     * 3.右子树
     * @return
     */
    public String preOrder(){
        if(root == null){
            return null;
        }
        StringBuffer result = new StringBuffer();
        preOrderTree(root,result);
        return result.toString();
    }
    private void preOrderTree(Node node,StringBuffer result){
        if(node == null){
            return;
        }
        //1.当前结点
        result.append(node.ele+"---");
        //2.左子树
        preOrderTree(node.left,result);
        //右子树
        preOrderTree(node.right,result);
    }

    //后序遍历

    /**
     * 1.左子树
     * 2.右子树
     * 3.当前结点
     * @return
     */
    public String subOrder(){
        if(root == null){
            return null;
        }
        StringBuffer result = new StringBuffer();
        subOrderTree(root,result);
        return result.toString();
    }
    private void subOrderTree(Node node,StringBuffer result){
        if(node == null){
            return;
        }
        //左子树
        subOrderTree(node.left,result);
        //右子树
        subOrderTree(node.right,result);
        //当前结点
        result.append(node.ele+"---");
    }

    //中序遍历
    /**
     * 1.左子树
     * 2.当前结点
     * 3.右子树
     */
    public String middleOrder(){
        if(root == null){
            return null;
        }
        StringBuffer result = new StringBuffer();
        middleOrderTree(root,result);
        return result.toString();
    }
    private void middleOrderTree(Node node,StringBuffer result){
        if(node == null){
            return;
        }
        //左子树
        middleOrderTree(node.left,result);
        //当前结点
        result.append(node.ele+"---");
        //右子树
        middleOrderTree(node.right,result);
    }

    //层序遍历
    public String levelOrder(){
        StringBuffer result = new StringBuffer();
        Queue<Node> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()){
            Node node = queue.poll();
            result.append(node.ele+"---");
            if(node.left !=  null){
                queue.offer(node.left);
            }
            if(node.right != null){
                queue.offer(node.right);
            }
        }
        return result.toString();
    }

    //查找二分搜索树最小值
    public Node findMinNode(){
        if(root == null){
            return null;
        }
        Node cur = root;
        while (cur.left != null){
            cur = cur.left;
        }
        return cur;
    }

    //删除最小值
    public T removeMin(){
        Node delNode = findMinNode();
        if(delNode == null){
            return null;
        }
        if(delNode == root && root.right != null){
            size--;
            root = root.right;
        }else if(delNode == root && root.right == null){
            size--;
            root = null;
        }else {
            removeMinNode(root);
        }

        return (T)delNode.ele;
    }
    private Node removeMinNode(Node node){
        if(node == null){
            return null;
        }
        if(node.left != null){
            node.left = removeMinNode(node.left);
        }else if(node.left == null && node.right != null){
            size--;
            node = node.right;
        }else if(node.left == null && node.right == null){
            size--;
            node = null;
        }
        return node;
    }

    //查找二分搜索树最大值
    public Node findMaxNode(){
        if(root == null){
            return null;
        }
        Node cur = root;
        while (cur.right != null){
            cur = cur.right;
        }
        return cur;
    }

    //删除最大值
    public T removeMax(){
        Node delNode = findMaxNode();
        if(delNode == null){
            return null;
        }
        if(delNode == root && root.left != null){
            size--;
            root = root.left;
        }else if(delNode == root && root.left == null){
            size--;
            root = null;
        }else {
            removeMaxNode(root);
        }

        return (T)delNode.ele;
    }
    private Node removeMaxNode(Node node){
        if(node == null){
            return null;
        }
        if(node.right != null){
            node.right = removeMaxNode(node.right);
        }else if(node.right == null && node.left != null){
            size--;
            node = node.left;
        }else  if(node.right == null && node.left == null){
            size--;
            node = null;
        }
        return node;
    }
}

测试:

    public void BSTtest(){
        BST<Integer> bst = new BST<>();
        int arr[] = {1,3,4,2,5};
        for(int i = 0;i<arr.length;i++){
            bst.add(arr[i]);
        }
        System.out.println("tree size:"+bst.getSize());//tree size:5
        //System.out.println(bst.isEmpty());//false
        //System.out.println(bst.preOrder());//1---3---2---4---5---
        //System.out.println(bst.contains(1));//true
        //System.out.println(bst.subOrder());//2---5---4---3---1---
        //System.out.println(bst.middleOrder());//1---2---3---4---5---
        //System.out.println(bst.levelOrder());//1---3---2---4---5---
        System.out.println(bst.removeMin());//1
        System.out.println(bst.middleOrder());//2---3---4---5---
        System.out.println("tree size:"+bst.getSize());//4
        System.out.println(bst.removeMax());//5
        System.out.println(bst.middleOrder());//2---3---4---
        System.out.println("tree size:"+bst.getSize());//tree size:3

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值