数据结构 二分搜索树
介绍
概念
数据结构中的二分搜索树是一种特殊的二叉搜索树,它的每个节点的值都大于或等于其左子树中所有节点的值,且小于或等于其右子树中所有节点的值。这种树在查找、插入和删除操作上都有很高的效率。
优缺点
二分搜索树的优点是可以快速地进行查找、插入和删除操作,而且它可以保证查找、插入和删除操作的时间复杂度都是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 发布!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。