Skip to content

二叉搜索树

示例:10000 个乱序的数,查找指定的元素

const arr = [] // 存放乱序的数
// 生成1万个乱序的数
for (let i = 0; i < 10000; i++) {
arr[i] = Math.floor(Math.random() * 10000)
}
let count = 0 // 计数器,用于对查找的次数进行计数
// 查找指定的元素
function search(arr, target) {
for (let i = 0; i < arr.length; i++) {
count++
if (arr[i] === target) return true
}
return false
}
console.log(search(arr, 7))
console.log(`用了${count}次查找`)

这种方式,实际上是比较低效的。如何优化呢?

  1. 算法
  2. 数据结构:数据结构上面有很大的优化空间,可以将其优化为一颗二叉搜索树。

二叉搜索树

二叉搜索树,英语是 Binary Search Tree,简称 BST,这是一种特殊的二叉树,其每个节点都包含一个键值,并且满足以下性质:

示例:对下面的数字构建二叉搜索树

;[3, 5, 1, 6, 7, 2, 9, 8]
  1. 取3作为根节点,然后取第二个元素5,因为5比 3 大,所以放在右边

    image-20250303100920906
  2. 取 1,比 3 小,所以将其放在左侧

    image-20250303101037293
  3. 接下来是 6,比 3 大,往右侧走,然后比 5 也大,因此放在 5 的右侧

    image-20250303101145399
  4. 接下来是 7,一层一层比下来,应该放在 6 的右侧

    image-20250303101314536
  5. 接下来是 2,比 3 小,所以走左边,比 1 大,成为 1 的右节点

    image-20250303101422019
  6. 接下来是 9,一路比下来,比 7 也大,成为 7 的右节点;

    最后是 8,一路比下来,比 9 小,因此成为 9 的左节点

    image-20250303101833915

代码实现

class TreeNode {
constructor(value) {
this.value = value
this.left = null
this.right = null
}
}
/**
* arr - 要构建的二叉搜索树的序列
*/
function buildSearchTree(arr) {
if (arr === null || arr.length === 0) return null
/**
* root - 父节点
* num - 当前节点
*/
function addNode(root, num) {
if (root === null || root.value === num) return
if (root.value < num) {
// 当前节点比父节点大,应该放在右边
if (root.right === null) {
// 当前父节点没有右子树,那么当前节点直接成为新的右子树即可
root.right = new TreeNode(num)
} else {
addNode(root.right, num)
}
} else {
// 当前节点比父节点小,应该放在左边
if (root.left === null) root.left = new TreeNode(num)
else addNode(root.left, num)
}
}
const root = new TreeNode(arr[0]) // 最上层的根节点
// 注意这里 i 是从 1 开始的,因为第一个元素已经根节点了
for (let i = 1; i < arr.length; i++) {
addNode(root, arr[i])
}
return root
}
const arr = [3, 5, 1, 6, 7, 2, 9, 8]
const bst = buildSearchTree(arr)
console.log(bst)
function inOrder(root) {
if (root === null) return
inOrder(root.left)
console.log(root.value)
inOrder(root.right)
}
inOrder(bst)

接下来,我们想要使用二叉搜索树进行一个搜索。

const arr = [3, 5, 1, 6, 7, 2, 9, 8]
const bst = buildSearchTree(arr)
function searchByBST(root, target) {
if (root === null) return false
// 下面的逻辑有一点类似于二分查找
if (root.value === target) return true
if (root.value > target) return searchByBST(root.left, target)
else return searchByBST(root.right, target)
}
console.log(searchByBST(bst, 5))

-EOF-