版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
描述
二叉搜索树的主要目标是优化链表的搜索效率。在链表中查找一个元素的时间复杂度为O(N),在二叉搜索树中查找一个元素的时间复杂度则为O(logN)。
在二叉搜索树中
- 左子节点的值小于根节点的值
- 右子节点的值大于根节点的值
我个人理解时,把二分搜索树理解为二分查找。
对于二叉搜索树的操作主要包括插入、查找、删除、遍历等。下面直接看代码。
代码实现
package loop;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
//二分搜索树
public class BST01<E extends Comparable<E>> {
private Node<E> root;
private int size;
/**
* 添加元素.
* @param e
* */
public void add(E e) {
root = add(root, e);
}
private Node<E> add(Node<E> node, E e) {
if (node == null) {
this.size ++;
return new Node<>(e);
}
if (e.compareTo(node.data) > 0) {
node.right = add(node.right, e);
} else if (e.compareTo(node.data) < 0) {
node.left = add(node.left, e);
}
return node;
}
/**
* 判断是否包含.
* @param e
* @return boolean
* */
public boolean contains(E e) {
return contains(root, e);
}
private boolean contains(Node<E> node, E e) {
if (node == null) {
return false;
}
if (e.compareTo(node.data) > 0) {
return contains(node.right, e);
} else if (e.compareTo(node.data) < 0) {
return contains(node.left, e);
}
return true;
}
//找到最小节点
private Node<E> findMin(Node node) {
if (node == null) {
return null;
}
if (node.left == null) {
return node;
}
return findMin(node.left);
}
private Node<E> findMax(Node<E> node) {
if (node == null) {
return null;
}
if (node.right == null) {
return node;
}
return findMax(node.right);
}
public E min() { return findMin(root).data; }
public E max() { return findMax(root).data; }
public void deleteMax() { deleteMax(root); }
public void deleteMin() { deleteMin(root); }
public void delete(E e) {
root = delete(root, e);
}
/**
* 删除最大值.
* @param node
* @return Node
* */
private Node<E> deleteMax(Node<E> node) {
if (node.right == null) {
Node<E> left = node.left;
node.left = null;
this.size --;
return left;
}
node.right = deleteMax(node.right);
return node;
}
/**
* 删除最小值.
* @param node
* @return Node
* */
private Node<E> deleteMin(Node<E> node) {
if(node.left == null) {
Node<E> right = node.right;
node.right = null;
this.size --;
return right;
}
node.left = deleteMin(node.left);
return node;
}
private Node<E> delete(Node<E> node, E e) {
if (node == null) {
return null;
}
if (e.compareTo(node.data) > 0) {
node.right = delete(node.right, e);
return node;
} else if (e.compareTo(node.data) < 0) {
node.left = delete(node.left, e);
return node;
} else {
//找到了
//找到右子树种的最小值
Node<E> rightMinNode = findMin(node.right);
//将最小的节点从右子树种删除
rightMinNode.right = deleteMin(node.right);
rightMinNode.left = node.left;
node.left = node.right = null;
this.size --;
return rightMinNode;
}
}
/**
* 前序遍历(递归)
* */
public void preOrder1() {
preOrder(root);
}
private void preOrder(Node<E> node) {
if (node == null) {
return;
}
E data = node.data;
System.out.println(data);
preOrder(node.left);
preOrder(node.right);
}
/**
* 前序遍历 非递归
* */
public void preOrder2() {
Stack<Node<E>> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
Node<E> cur = stack.pop();
System.out.println(cur.data);
if (cur.right != null) {
stack.push(cur.right);
}
if (cur.left != null) {
stack.push(cur.left);
}
}
}
/**
* 广度优先遍历
* */
public void print() {
Queue<Node<E>> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
Node<E> cur = queue.remove();
System.out.println(cur.data);
if (cur.left != null) {
queue.add(cur.left);
}
if(cur.right != null) {
queue.add(cur.right);
}
}
}
public int getSize() { return this.size; }
public boolean isEmpty() { return this.size == 0; }
// 节点定义
private class Node<E> {
public E data;
public Node<E> left;
public Node<E> right;
public Node(E data) {
this.data = data;
this.left = null;
this.right = null;
}
}
}