JavaScript 数据结构-二叉搜索树

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // 封装二叉树类
        function BinarySerachTree() {
            // 节点类
            function Node(key) {
                this.key = key
                this.left = null
                this.right = null
            }

            // 属性
            this.root = null //根节点

            // 方法
            // 插入数据:对外给用户调用
            BinarySerachTree.prototype.insert = function (key) {
                // 1.根据key创建节点
                var newNode = new Node(key)

                // 2.判断根节点是否有值
                if (this.root == null) {
                    this.root = newNode
                } else {
                    this.insertNode(this.root, newNode)
                }
            }

            // 第一次: node->9  newNode->14
            // 第二次: node->13 newNode->14
            // 第四次: node->15 newNode->14
            BinarySerachTree.prototype.insertNode = function (node, newNode) {
                if (newNode.key < node.key) { //向左查找
                    if (node.left == null) {
                        node.left = newNode
                    } else {
                        this.insertNode(node.left, newNode)
                    }
                } else { //向右查找
                    if (node.right == null) {
                        node.right = newNode
                    } else {
                        this.insertNode(node.right, newNode)
                    }
                }
            }

            // 树的遍历
            // 1.先序遍历
            BinarySerachTree.prototype.preOrderTraversal = function (handler) {
                this.preOrderTraversalNode(this.root, handler)
            }
            // 第一次: node->11
            // 第二次: node->7
            // 第三次: node->5
            BinarySerachTree.prototype.preOrderTraversalNode = function (node, handler) {
                if (node != null) {
                    // 1.处理经过的节点
                    handler(node.key)

                    // 2.查找经过节点的左子节点
                    this.preOrderTraversalNode(node.left, handler)

                    // 3.查找经过节点的右子节点
                    this.preOrderTraversalNode(node.right, handler)
                }
            }

            // 2.中序遍历
            BinarySerachTree.prototype.midOrderTraversal = function (handler) {
                this.midOrderTraversalNode(this.root, handler)
            }

            BinarySerachTree.prototype.midOrderTraversalNode = function (node, handler) {
                if (node != null) {
                    // 1.查找左子树中的节点
                    this.midOrderTraversalNode(node.left, handler)

                    // 2.处理节点
                    handler(node.key)

                    // 3.查找右子树中的节点
                    this.midOrderTraversalNode(node.right, handler)
                }
            }

            // 3.后序遍历
            BinarySerachTree.prototype.postOrderTraversal = function (handler) {
                this.postOrderTraversalNode(this.root, handler)
            }

            BinarySerachTree.prototype.postOrderTraversalNode = function (node, handler) {
                if (node != null) {
                    // 1.查找左子树中的节点
                    this.postOrderTraversalNode(node.left, handler)

                    // 3.查找右子树中的节点
                    this.postOrderTraversalNode(node.right, handler)

                    // 2.处理节点
                    handler(node.key)
                }
            }

            // 寻找最值
            // 1.寻找最大值
            BinarySerachTree.prototype.max = function () {
                // 1.获取根节点
                var node = this.root

                // 2.依次向右不断查找,直到节点为null
                var key = null
                while (node != null) {
                    key = node.key
                    node = node.right
                }

                return key
            }

            // 2.寻找最小值
            BinarySerachTree.prototype.min = function () {
                // 1.获取根节点
                var node = this.root

                // 2.依次向左不断查找,直到节点为null
                var key = null
                while (node != null) {
                    key = node.key
                    node = node.left
                }

                return key
            }

            // 3.查询某个特定的值是否存在
            BinarySerachTree.prototype.search = function (key) {
                // 1.获取根节点
                var node = this.root

                // 2.循环搜索key
                while (node != null) {
                    if (key < node.key) {
                        node = node.left
                    } else if (key > node.key) {
                        node = node.right
                    } else {
                        return true
                    }
                }

                // 循环结束返回false
                return false
            }

            // 删除节点
            BinarySerachTree.prototype.remove = function (key) {
                // 1.寻找要删除的节点
                // 1.1定义变量,保存一些信息
                var current = this.root
                var parent = null
                var isLeftChild = true

                // 1.2开始寻找删除的节点
                while (current.key != key) {
                    parent = current
                    if (key < current.key) {
                        isLeftChild = true
                        current = current.left
                    } else {
                        isLeftChild = false
                        current = current.right
                    }

                    // 已经找到了最后的节点,依然没有找到==key 
                    if (current == null) return false
                }

                // 2.根据对应的情况删除节点
                // 2.1删除的节点是叶子节点(没有子节点)
                if (current.left == null && current.right == null) {
                    if (current == this.root) {
                        this.root = null
                    } else if (isLeftChild) {
                        parent.left = null
                    } else {
                        parent.right = null
                    }
                } else if (current.right == null) { // 2.2删除的节点有一个子节点
                    if (current == this.root) {
                        this.root = current.left
                    } else if (isLeftChild) {
                        parent.left = current.left
                    } else {
                        parent.right = current.left
                    }
                } else if (current.left == null) {
                    if (current == this.root) {
                        this.root = current.right
                    } else if (isLeftChild) {
                        parent.left = current.right
                    } else {
                        parent.right = current.right
                    }
                } else { // 2.3删除的节点有两个子节点
                    // 1.获取后继节点
                    var successor = this.getSuccssor(current)

                    // 2.判断是否根节点
                    if (current == this.root) {
                        this.root = successor
                    } else if (isLeftChild) {
                        parent.left = successor
                    } else {
                        parent.right = successor
                    }

                    // 3.将删除节点的左子树 = current.left
                    successor.left = current.left
                }
            }

            // 找后继的方法
            BinarySerachTree.prototype.getSuccssor = function (delNode) {
                // 1.定义变量,保存找到的后继
                var successor = delNode
                var current = delNode.right
                var successorParent = delNode

                // 2.循环查找
                while (current != null) {
                    successorParent = successor
                    successor = current
                    current = current.left
                }

                // 3.判断寻找的后继节点是否直接就是delNode的right节点
                if (successor != delNode.right) {
                    successorParent.left = successor.right
                    successor.right = delNode.right
                }

                return successor
            }
        }

        // 测试
        // 1.创建BinarySerachTree
        var bst = new BinarySerachTree()

        // 2.插入数据
        bst.insert(11)
        bst.insert(7)
        bst.insert(15)
        bst.insert(5)
        bst.insert(3)
        bst.insert(9)
        bst.insert(6)
        bst.insert(8)
        bst.insert(10)
        bst.insert(13)
        bst.insert(12)
        bst.insert(14)
        bst.insert(20)
        bst.insert(18)
        bst.insert(25)

        // 3.测试遍历
        // 1.测试先序遍历
        var result = ''
        bst.preOrderTraversal(function (key) {
            result += key + ' '
        })
        // alert(result)

        // 2.测试中序遍历
        result = ''
        bst.midOrderTraversal(function (key) {
            result += key + ' '
        })
        // alert(result)

        // 3.测试后序遍历
        result = ''
        bst.postOrderTraversal(function (key) {
            result += key + ' '
        })
        // alert(result)

        // 4.测试最值
        // alert(bst.max())
        // alert(bst.min())

        // 5.测试查询方法
        // alert(bst.search(25))
        // alert(bst.search(24))
        // alert(bst.search(2))

        // 6.测试删除方法
        // bst.remove(11)
        // bst.remove(7)
        // bst.remove(15)
        // result = ''
        // bst.postOrderTraversal(function (key) {
        //     result += key + ' '
        // })
        // alert(result)
    </script>
</body>

</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值