【无标题】【前端】自学基础算法 -- 16.二叉搜索树

二叉搜索树

简介

二叉搜索树是一种二叉树,它满足以下性质:对于树中的任意一个节点,其左子树中的所有节点的值都小于该节点的值,其右子树中的所有节点的值都大于该节点的值。这种数据结构支持高效的搜索操作,例如,在一个二叉搜索树中查找一个特定的值,每次可以根据当前节点的值与目标值的比较结果,决定是在左子树还是右子树中继续搜索。

效率对比

1. 搜索操作效率对比
  • 二叉搜索树: 在平均情况下,二叉搜索树的搜索操作时间复杂度为。这是因为每次比较节点的值后,可以排除树的一半左右(左子树或右子树)。例如,在一个比较平衡的二叉搜索树中,如果树的高度为,且个节点大致均匀分布,那么左右。
  • 暴力循环(线性搜索): 如果是对一个无序的数组进行暴力循环搜索,时间复杂度为。因为在最坏的情况下,需要遍历整个数组才能确定元素是否存在。例如,在一个有个元素的数组中查找一个特定元素,平均需要检查个元素。
2. 插入操作效率对比
  • 二叉搜索树: 平均时间复杂度为。插入新节点时,从根节点开始,根据节点值与当前节点值的比较结果,决定向左子树还是右子树移动,直到找到合适的插入位置。在平衡的二叉搜索树中,插入操作的效率较高。
  • 暴力循环(假设插入到数组中): 如果是将一个元素插入到数组中,在不考虑数组扩容的情况下,平均时间复杂度为。因为可能需要移动插入位置之后的所有元素来为新元素腾出空间。
3. 删除操作效率对比
  • 二叉搜索树: 平均时间复杂度为。删除操作需要考虑多种情况,如删除叶子节点、只有一个子节点的节点和有两个子节点的节点。在平衡的二叉搜索树中,通过适当的调整可以保持树的结构,并且操作效率较高。
  • 暴力循环(假设从数组中删除): 从数组中删除元素,在不考虑元素移动的优化情况下,平均时间复杂度为。因为删除一个元素后,可能需要将后面的元素向前移动来填补空缺。

示例方法

查找一个数,在一个数组/二叉树中是否存在

一、暴力搜索

num 数值普遍较大,循环次数多

let arr = []

for (let i = 0; i < 1000; i++) {
  arr[i] = Math.floor(Math.random() * 1000)
}

let num = 0
function search(arr, target) {
  for (let i = 0; i < arr.length; i++) {
    num += 1
    if (arr[i] === target) return true
  }
  return false
}

console.log(search(arr, 888))
console.log(num)

二、使用二叉搜索树

num2数值普遍较小,循环次数少

class Node {
  constructor(value) {
    this.value = value
    this.left = null
    this.right = null
  }
}

// 辅助函数 - 添加节点
function addNode(root, num) {
  if (root === null) return
  if (root.value === num) return
  if (root.value > num) {
    // 目标值比当前节点小
    if (root.left === null) root.left = new Node(num)
    else addNode(root.left, num)
  } else {
    // 目标值比当前节点大
    if (root.right === null) root.right = new Node(num)
    else addNode(root.right, num)
  }
}

// 辅助函数 - 构建二叉搜索树
function buildSearchTree(arr) {
  if (arr == null || arr.length === 0) return null
  let root = new Node(arr[0])
  for (let i = 1; i < arr.length; i++) {
    addNode(root, arr[i])
  }
  return root
}

let num2 = 0
// 辅助函数 - 使用搜索二叉树查询
function searchByTree(root, target) {
  if (root == null) return false
  num2++
  if (root.value === target) return true
  if (root.value > target) return searchByTree(root.left, target)
  else return searchByTree(root.right, target)
}

let root = buildSearchTree(arr)
console.log(searchByTree(root, 888))
console.log(num2)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值