Skip to content

Binary Search Tree

基础的二分搜索树

定义

操作定义

interface BST<K : Comparable<K>, V> : KVOperation<K, V> {

    /**
     * Retrieves the root node of the binary search tree (BST).
     *
     * @return the root node of the BST, or null if the tree is empty
     */
    fun getRoot(): BSTNode<K, V>?

    /**
     * Determines whether the binary search tree (BST) contains the specified key.
     *
     * @param key the key to search for in the binary search tree
     * @return true if the key exists in the tree, false otherwise
     */
    override fun contains(key: K): Boolean {
        return getNode(key) != null
    }

    /**
     * Retrieves the value associated with the specified key in the binary search tree (BST).
     */
    override fun get(key: K): V? {
        return getNode(key)?.getValue()
    }

    /**
     * Retrieves the node associated with the specified key in the binary search tree (BST).
     *
     * @param key the key to search for in the binary search tree
     * @return the node corresponding to the given key, or null if the key is not found
     */
    fun getNode(key: K): BSTNode<K, V>? {
        return getNode(getRoot(), key)
    }

    /**
     * Determines whether the binary search tree (BST) satisfies the properties of a valid BST.
     *
     * @return true if the tree is a valid binary search tree, false otherwise
     */
    fun isBst(): Boolean {
        return isBST(node = getRoot())
    }

    /**
     * Retrieves the minimum node in the binary search tree (BST).
     *
     * @return the node containing the smallest key in the tree, or null if the tree is empty
     */
    fun getMin(): BSTNode<K, V>? {
        return getMin(getRoot())
    }

    /**
     * Retrieves the maximum node in the binary search tree (BST).
     *
     * @return the node containing the largest key in the tree, or null if the tree is empty
     */
    fun getMax(): BSTNode<K, V>? {
        return getMax(getRoot())
    }

    fun preorder(action: (BSTNode<K, V>) -> Unit) {
        getRoot()?.preorder(action)
    }

    fun inorder(action: (BSTNode<K, V>) -> Unit) {
        getRoot()?.inorder(action)
    }

    fun postorder(action: (BSTNode<K, V>) -> Unit) {
        getRoot()?.postorder(action)
    }

    fun bfs(action: (BSTNode<K, V>) -> Unit) {
        getRoot()?.bfs(action)
    }

    fun <K : Comparable<K>, V> BSTNode<K, V>.preorder(action: (BSTNode<K, V>) -> Unit) {
        action.apply { this }

        getLeft()?.preorder(action)
        getRight()?.preorder(action)
    }

    fun <K : Comparable<K>, V> BSTNode<K, V>.inorder(action: (BSTNode<K, V>) -> Unit) {
        getLeft()?.inorder(action)
        action.apply { this }
        getRight()?.inorder(action)
    }

    fun <K : Comparable<K>, V> BSTNode<K, V>.postorder(action: (BSTNode<K, V>) -> Unit) {
        getLeft()?.postorder(action)
        getRight()?.postorder(action)
        action.apply { this }
    }

    fun <K : Comparable<K>, V> BSTNode<K, V>.bfs(action: (BSTNode<K, V>) -> Unit) {
        val queue = ArrayDeque<BSTNode<K, V>>()
        queue.add(this)

        while (queue.isNotEmpty()) {
            val current = queue.removeFirst()
            action(current)

            current.getLeft()?.let { queue.addLast(it) }
            current.getRight()?.let { queue.addLast(it) }
        }
    }

}

节点定义

interface BSTNode<K : Comparable<K>, V> {

    /**
     * 节点高度,定义为节点到根节点的高度
     */
    fun getHeight(): Int

    fun setHeight(height: Int): BSTNode<K, V>

    fun getKey(): K

    fun setKey(key: K): BSTNode<K, V>

    fun getValue(): V

    fun setValue(value: V): BSTNode<K, V>

    fun getLeft(): BSTNode<K, V>?

    fun setLeft(left: BSTNode<K, V>?): BSTNode<K, V>

    fun getRight(): BSTNode<K, V>?

    fun setRight(right: BSTNode<K, V>?): BSTNode<K, V>

    fun isLeaf(): Boolean {
        return this.getLeft() == null && this.getRight() == null
    }
}

实现

class BasicBST<K : Comparable<K>, V> : BST<K, V> {
    private var root: BSTNode<K, V>? = null
    private var count = 0

    override fun size(): Int = this.count

    override fun getRoot(): BSTNode<K, V>? = this.root

    /**
     * Adds a key-value pair to the binary search tree (BST). If the key already exists,
     * updates the value associated with the key.
     *
     * @param key the key to insert or update in the BST
     * @param value the value to associate with the specified key
     */
    override fun insert(key: K, value: V) {
        root = add(root, key, value)
    }

    private fun add(node: BSTNode<K, V>?, k: K, v: V): BSTNode<K, V> {
        if (node == null) {
            count++
            return BasicBSTNode(k, v)
        }

        when {
            k < node.getKey() -> node.setLeft(add(node.getLeft(), k, v))

            k > node.getKey() -> node.setRight(add(node.getRight(), k, v))

            else -> {
                node.setValue(v)
            }
        }
        return node.updateHeight()
    }

    override fun remove(k: K): V? {
        return getNode(k)?.let { node ->
            val rtV = node.getValue()
            root = remove(root, k)
            rtV
        }
    }

    private fun remove(node: BSTNode<K, V>?, k: K): BSTNode<K, V>? {
        if (node == null) {
            return null
        }
        when {
            k < node.getKey() -> {
                node.setLeft(remove(node.getLeft(), k))
            }

            k > node.getKey() -> {
                node.setRight(remove(node.getRight(), k))
            }

            else -> {
                // Node to be removed found
                if (node.getLeft() == null && node.getRight() == null) {
                    // 左右子节点都为空
                    this.count--
                    return null
                }
                // 剩余三种情况  左不空+右不空 左不空+右空  左空+右不空
                node.getLeft()?.let { leftChild ->
                    // 左不空+右不空 左不空+右空
                    getMax(leftChild)!!.let { leftMax ->
                        node.setKey(leftMax.getKey())
                            .setValue(leftMax.getValue())
                            .setLeft(remove(leftChild, leftMax.getKey()))
                    }
                } ?: run {
                    // 左空+右不空:选择右子树最小值作为替换节点
                    getMin(node.getRight())!!.let { rightMin ->
                        node.setKey(rightMin.getKey())
                            .setValue(rightMin.getValue())
                            .setRight(remove(node.getRight(), rightMin.getKey()))
                    }
                }
            }
        }
        return node.updateHeight()
    }

    override fun clear() {
        this.root = null
        this.count = 0
    }
}

internal class BasicBSTNode<K : Comparable<K>, V> : BSTNode<K, V> {
    private var height: Int
    private var key: K
    private var value: V
    private var left: BSTNode<K, V>?
    private var right: BSTNode<K, V>?

    internal constructor(key: K, value: V) {
        this.key = key
        this.value = value
        this.height = DEFAULT_HEIGHT
        this.left = null
        this.right = null
    }

    override fun getHeight(): Int = height

    override fun setHeight(height: Int): BSTNode<K, V> {
        this.height = height
        return this
    }

    override fun getKey(): K = this.key

    override fun setKey(key: K): BSTNode<K, V> = this.apply {
        this.key = key
    }

    override fun getValue(): V = this.value

    override fun setValue(value: V): BSTNode<K, V> = this.apply {
        this.value = value
    }

    override fun getLeft(): BSTNode<K, V>? = this.left

    override fun setLeft(left: BSTNode<K, V>?): BSTNode<K, V> = this.apply {
        this.left = left
    }

    override fun getRight(): BSTNode<K, V>? = this.right

    override fun setRight(right: BSTNode<K, V>?): BSTNode<K, V> = this.apply {
        this.right = right
    }

    override fun toString(): String {
        return "BSTNode(key=$key, value=$value)"
    }

}

问题

普通的二分搜索树在极端情况下会退化成链表