二分搜索树

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() {
}

你可能感兴趣的:(二分搜索树)