二分搜索树,让你的程序效率飙升!

数据结构 二分搜索树

介绍

概念

数据结构中的二分搜索树是一种特殊的二叉搜索树,它的每个节点的值都大于或等于其左子树中所有节点的值,且小于或等于其右子树中所有节点的值。这种树在查找、插入和删除操作上都有很高的效率。

优缺点

二分搜索树的优点是可以快速地进行查找、插入和删除操作,而且它可以保证查找、插入和删除操作的时间复杂度都是O(log n)。这使得二分搜索树成为许多应用程序中常用的数据结构之一,例如数据库索引、排序等。

但是,二分搜索树也存在一些缺点。由于它的非平衡性,当树很大时,性能可能会变得很差。此外,由于它需要维护每个节点的键值对顺序,因此空间复杂度通常比其他平衡二叉树高。

使用场景

二分搜索树的应用场景包括:在大型数据库中快速查找特定记录;在需要快速查找、插入和删除元素的应用程序中使用;在需要对大量数据进行排序或去重的应用程序中使用;在需要对大量数据进行分析或统计的应用程序中使用。

设计

int getSize();

boolean isEmpty();

boolean contains(E e);//二分搜索树中是否包含元素E

void add(E e);//向二分搜索树中添加元素E

E getMinElement();//获取二分搜索树中的最小元素

E getMaxElement();//获取二分搜索树中的最大元素

E removeMin();//删除二分搜索树中的最小元素

E removeMax();//删除二分搜索树中的最大元素

void remove(E e);//删除二分搜索树中的元素E

void levelOrder();//层序遍历二分搜索树

void preOrder();//前序遍历二分搜索树

void postOrder();//后序遍历二分搜索树

void inOrder();//中序遍历二分搜索树

实现

package com.sssd.learns.structure;

import java.util.LinkedList;
import java.util.Objects;
import java.util.Queue;

/**
 * @author sssd
 * @careate 2023-07-18-18:04
 */
public class BST2<E extends Comparable<E>> {

    private class Node {
        E e;
        Node left;
        Node right;

        Node(E e) {
            this.e = e;
            this.left = null;
            this.right = null;
        }
    }

    private Node root;

    private int size;

    public BST2() {
        this.root = null;
        this.size = 0;
    }

    public int getSize() {
        return size;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    public boolean contains(E e) {
        return contains(root, e);
    }

    private boolean contains(Node node, E e) {
        if (Objects.isNull(node)) {
            return false;
        }
        if (e.compareTo(node.e) < 0) {
            return contains(node.left, e);
        } else if (e.compareTo(node.e) > 0) {
            return contains(node.right, e);
        }
        return true;
    }

    public void add(E e) {
        root = add(root, e);
    }

    public Node add(Node node, E e) {
        if (Objects.isNull(node)) {
            size++;
            return new Node(e);
        }
        if (e.compareTo(node.e) < 0) {
            node.left = add(node.left, e);
        } else if (e.compareTo(node.e) > 0) {
            node.right = add(node.right, e);
        }
        return node;
    }

    /**
     * 前序遍历
     */
    public void preOrder() {
        preOrder(root);
    }

    private void preOrder(Node node) {
        if (Objects.isNull(node)) {
            return;
        }
        System.out.println(node.e);
        preOrder(node.left);
        preOrder(node.right);
    }

    /**
     * 中序遍历
     */
    public void inOrder() {
        inOrder(root);
    }

    private void inOrder(Node node) {
        if (Objects.isNull(node)) {
            return;
        }
        inOrder(node.left);
        System.out.println(node.e);
        inOrder(node.right);
    }

    /**
     * 后序遍历
     */
    public void postOrder() {
        postOrder(root);
    }

    private void postOrder(Node node) {
        if (Objects.isNull(node)) {
            return;
        }
        postOrder(node.left);
        postOrder(node.right);
        System.out.println(node.e);
    }

    /**
     * 层序遍历
     */
    public void levelOrder() {
        Queue<Node> queue = new LinkedList<Node>();
        queue.add(root);
        while (!queue.isEmpty()) {
            Node cur = queue.remove();
            System.out.println(cur.e);
            if (Objects.nonNull(cur.left)) {
                queue.add(cur.left);
            }
            if (Objects.nonNull(cur.right)) {
                queue.add(cur.right);
            }
        }
    }

    /**
     * 获取二分搜索树中的最小值
     *
     * @return
     */
    public E getMinElement() {
        if (isEmpty()) {
            throw new IllegalArgumentException("BST is empty..");
        }
        return getMinElement(root).e;
    }

    public Node getMinElement(Node node) {
        if (Objects.isNull(node.left)) {
            return node;
        }
        return getMinElement(node.left);
    }

    /**
     * 获取二分搜索树中的最大值
     */
    public E getMaxElement() {
        if (isEmpty()) {
            throw new IllegalArgumentException("BST is empty..");
        }
        return getMaxElement(root).e;
    }

    private Node getMaxElement(Node node) {
        if (Objects.isNull(node.right)) {
            return node;
        }
        return getMaxElement(node.right);
    }

    /**
     * 删除二分搜索树的最小值
     *
     * @return
     */
    public E removeMin() {
        E removeElement = getMinElement();
        root = removeMin(root);
        return removeElement;
    }

    private Node removeMin(Node node) {
        if (Objects.isNull(node.left)) {
            Node rightNode = node.right;
            node.right = null;
            size--;
            return rightNode;
        }
        node.left = removeMin(node.left);

        return node;
    }

    /**
     * 删除二分搜索树的最大值
     *
     * @return
     */
    public E removeMax() {
        E maxElement = getMaxElement();
        root = removeMax(root);
        return maxElement;
    }

    private Node removeMax(Node node) {
        if (Objects.isNull(node.right)) {
            Node leftNode = node.left;
            node.right = null;
            size--;
            return leftNode;
        }
        node.right = removeMin(node.right);
        return node;
    }

    /**
     * 删除二分搜索树中的元素E
     * @param e
     */
    public void remove(E e) {
        root = remove(root, e);
    }

    private Node remove(Node node, E e) {
        if (node == null) {
            return null;
        }
        if (e.compareTo(node.e) < 0) {
            node.left = remove(node.left, e);
            return node;
        } else if (e.compareTo(node.e) > 0) {
            node.right = remove(node.right, e);
            return node;
        } else { //e.compareTo(node.e) == 0
            if (node.left == null) {
                Node rightNode = node.right;
                node.right = null;
                size--;
                return rightNode;
            }
            if (node.right == null) {
                Node leftNode = node.left;
                node.right = null;
                size--;
                return leftNode;
            }
            Node successor = getMinElement(node.right);
            successor.right = removeMin(node.right);
            successor.left = node.right;

            node.left = node.right = null;
            return successor;
        }
    }


}

作者:傻傻三多

出处:https://www.sssd.top/archives/1688033050884

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

本文由博客一文多发平台 OpenWrite 发布!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值