Java实现:
package bst;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
import java.util.Stack;
/**
* 二分搜索树
*
* @author ZhuZongxing
*/
public class BinarySearchTree> {
private class Node {
public E e;
public Node left;
public Node right;
public Node(E e, Node left, Node right) {
this.e = e;
this.left = left;
this.right = right;
}
public Node(E e) {
this(e, null, null);
}
}
private Node root;
private int size;
public BinarySearchTree() {
root = null;
size = 0;
}
public void add(E e) {
root = add(root, e);
}
private Node add(Node node, E e) {
if (node == null) {
size++;
return new Node(e);
}
if (e.compareTo(node.e) > 0) {
node.right = add(node.right, e);
} else if (e.compareTo(node.e) < 0) {
node.left = add(node.left, e);
}
return node;
}
public boolean contains(E e) {
return contains(root, e);
}
/**
* 以node为跟的二分搜索树是否存在元素e
*
* @param node node
* @param e e
* @return contains e
*/
private boolean contains(Node node, E e) {
if (e.compareTo(node.e) == 0) {
return true;
} else if (e.compareTo(node.e) > 0) {
return contains(node.right, e);
} else {
return contains(node.left, e);
}
}
public E minimum() {
if (size == 0) {
return null;
}
return minimum(root).e;
}
public E maximum() {
if (size == 0) {
return null;
}
return maximum(root).e;
}
/**
* @param node node
* @return 以node为根的二分搜索树的最小值所在的节点
*/
private Node minimum(Node node) {
if (node.left != null) {
return minimum(node.left);
}
return node;
}
private Node maximum(Node node) {
if (node.right != null) {
return minimum(node.right);
}
return node;
}
public E removeMin() {
E minimum = minimum();
root = removeMin(root);
return minimum;
}
public E removeMax() {
E maximum = maximum();
root = removeMax(root);
return maximum;
}
/**
* 删除以node为根的二分搜索树中的最小节点
*
* @param node node
* @return 删除节点后的二分搜索树的根
*/
private Node removeMin(Node node) {
if (node.left == null) {
Node rightNode = node.right;
node.right = null;
size--;
return rightNode;
}
node.right = removeMin(node.left);
return node;
}
/**
* 删除以node为根的二分搜索树中的最小节点
*
* @param node node
* @return 删除节点后的二分搜索树的根
*/
private Node removeMax(Node node) {
if (node.right == null) {
Node rightNode = node.left;
node.left = null;
size--;
return rightNode;
}
node.left = removeMin(node.right);
return node;
}
public void remove(E e) {
root = remove(root, e);
}
/**
* 删除以Node为根的二分搜索树的e所在的Node
*
* @param node node
* @param e e
* @return 删除节点后二分搜索树的根
*/
private Node remove(Node node, E e) {
if (node == null) {
return null;
}
if (e.compareTo(node.e) > 0) {
node.right = remove(node.right, e);
return node;
} else if (e.compareTo(node.e) < 0) {
node.left = remove(node.left, e);
return node;
} else {
if (node.left == null) {
Node rightNode = node.right;
node.right = null;
size--;
return rightNode;
}
if (node.right == null) {
Node leftNode = node.left;
node.left = null;
size--;
return leftNode;
}
//待删除节点左右子树都不为空的情况
//找到比待删除节点大的最小节点,即待删除节点右子树的最小节点,用此节点替代待删除节点的位置
Node successor = minimum(node.right);
successor.right = removeMin(node.right);
successor.left = node.left;
node.left = node.right = null;
return successor;
}
}
//============================二分搜索树的深度优先遍历================================//
/**
* 前序遍历的非递归实现
*/
public void preTraverseNR() {
Stack stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
Node curNode = stack.pop();
System.out.println(curNode.e);
if (curNode.right != null) {
stack.push(curNode.right);
}
if (curNode.left != null) {
stack.push(curNode.left);
}
}
}
/**
* 二分搜索树的前序遍历
*/
public void prevTraverse() {
prevTraverse(root);
}
private void prevTraverse(Node node) {
if (node == null) {
return;
}
System.out.println(node.e);
prevTraverse(node.left);
prevTraverse(node.right);
}
/**
* 二分搜索树的中序遍历(按从小到大排序后的结果)
*/
public void inTraverse() {
inTraverse(root);
}
private void inTraverse(Node node) {
if (node == null) {
return;
}
inTraverse(node.left);
System.out.println(node.e);
inTraverse(node.right);
}
/**
* 二分搜索树的后序遍历
*/
public void postTraverse() {
postTraverse(root);
}
private void postTraverse(Node node) {
if (node == null) {
return;
}
postTraverse(node.left);
System.out.println(node.e);
postTraverse(node.right);
}
//============================二分搜索树的深度优先遍历================================//
//============================二分搜索树的广度优先遍历(层序遍历),可以更快找到元素================================//
public void breadthTraverse() {
Queue queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
Node curNode = queue.remove();
System.out.println(curNode.e);
if (curNode.left != null) {
queue.add(curNode.left);
}
if (curNode.right != null) {
queue.add(curNode.right);
}
}
}
//============================二分搜索树的广度优先遍历(层序遍历)================================//
public int getSize() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
@Override
public String toString() {
return null;
}
public static void main(String[] args) {
BinarySearchTree bst = new BinarySearchTree<>();
for (int i = 0; i < 10; i++) {
bst.add(new Random().nextInt(100));
}
bst.inTraverse();
}
}
Kotlin实现:
package bst
import java.util.*
/**
* 二分搜索树的Kotlin实现
* @author ZhuZongxing
*/
class BinarySearchTree> {
private inner class Node(var e: E, var left: Node?, var right: Node?) {
constructor(e: E) : this(e, null, null)
}
private var root: Node? = null
private var size: Int = 0
fun add(e: E) {
root = add(root, e)
}
private fun add(node: Node?, e: E): Node {
if (node == null) {
size++
return Node(e)
}
when {
e > node.e -> {
node.right = add(node.right, e)
}
e < node.e -> {
node.left = add(node.left, e)
}
}
return node
}
fun contains(e: E) = contains(root, e)
private fun contains(node: Node?, e: E): Boolean {
return when {
node == null -> {
false
}
e == node.e -> {
true
}
e > node.e -> {
contains(node.right, e)
}
else -> {
contains(node.left, e)
}
}
}
fun minimum(): E? {
if (size == 0) {
return null
}
return minimum(root)?.e
}
private fun minimum(node: Node?): Node? {
if (node == null) {
return null
}
if (node.left == null) {
return node
}
return minimum(node.left)
}
fun maximum(): E? {
if (size == 0) {
return null
}
return maximum(root)?.e
}
private fun maximum(node: Node?): Node? {
if (node == null) {
return null
}
if (node.right == null) {
return node
}
return maximum(node.right)
}
fun removeMin(): E? {
val minimum = minimum()
root = removeMin(root)
return minimum
}
private fun removeMin(node: Node?): Node? {
if (node == null) {
return null
}
if (node.left == null) {
val rightNode = node.right
node.right = null
size--
return rightNode
}
node.right = removeMin(node.left)
return node
}
fun removeMax(): E? {
val maximum = maximum()
root = removeMax(root)
return maximum
}
private fun removeMax(node: Node?): Node? {
if (node == null) {
return null
}
if (node.right == null) {
val leftNode = node.left
node.left = null
size--
return leftNode
}
node.left = removeMax(node.right)
return node
}
fun remove(e: E) {
root = remove(root, e)
}
private fun remove(node: Node?, e: E): Node? {
if (node == null) {
return null
}
when {
e > node.e -> {
node.right = remove(node.right, e)
return node
}
e < node.e -> {
node.left = remove(node.left, e)
return node
}
else -> {
if (node.left == null) {
val rightNode = node.right
node.right = null
size--
return rightNode
}
if (node.right == null) {
val leftNode = node.left
node.left = null
size--
return leftNode
}
val successor = minimum(node.right)
successor!!.right = removeMin(node.right)
successor.left = node.left
node.left = null
node.right = null
return successor
}
}
}
//============================二分搜索树的深度优先遍历================================//
fun preTraverseNR() {
val stack = Stack()
stack.push(root)
while (!stack.isEmpty()) {
val curNode = stack.pop()
println(curNode.e)
if (curNode.right != null) {
stack.push(curNode.right)
}
if (curNode.left != null) {
stack.push(curNode.left)
}
}
}
fun prevTraverse() {
preTraverse(root)
}
private fun preTraverse(node: Node?) {
if (node == null) {
return
}
println(node.e)
preTraverse(node.left)
preTraverse(node.right)
}
fun inTraverse() {
inTraverse(root)
}
private fun inTraverse(node: Node?) {
if (node == null) {
return
}
inTraverse(node.left)
println(node.e)
inTraverse(node.right)
}
fun postTraverse() {
postTraverse(root)
}
private fun postTraverse(node: Node?) {
if (node == null) {
return
}
postTraverse(node.left)
postTraverse(node.right)
println(node.e)
}
//============================二分搜索树的深度优先遍历================================//
//============================二分搜索树的广度优先遍历(层序遍历),可以更快找到元素================================//
fun breadthTraverse() {
val queue = LinkedList()
queue.add(root)
while (!queue.isEmpty()) {
val curNode = queue.remove() ?: return
println(curNode.e)
if (curNode.left != null) {
queue.add(curNode.left)
}
if (curNode.right != null) {
queue.add(curNode.right)
}
}
}
//============================二分搜索树的广度优先遍历(层序遍历),可以更快找到元素================================//
fun getSize() = size
fun isEmpty() = size == 0
override fun toString(): String {
val sb = StringBuilder()
toString(root, 0, sb)
return sb.toString()
}
private fun toString(node: Node?, depth: Int, sb: StringBuilder) {
if (node == null) {
sb.append("${toDepthString(depth)}null\n")
return
}
sb.append("${toDepthString(depth)} ${node.e}\n")
toString(node.left, depth + 1, sb)
toString(node.right, depth + 1, sb)
}
private fun toDepthString(depth: Int): String {
val sb = StringBuilder()
for (index in 0 until depth) {
sb.append("--")
}
return sb.toString()
}
}
fun main() {
}