算法:用JS实现二分查找,并说明时间复杂度

114 阅读1分钟

思路:

  • 递归 - 代码逻辑更加清晰
  • 非递归 - 性能更好
  • 时间复杂度O(logn) - 非常快

非递归实现:

function binarySearch1(arr: number[], target: number): number {
  const length = arr.length
  if (length === 0) return -1

  let startIndex = 0 // 开始位置
  let endIndex = length - 1 // 结束位置

  while (startIndex <= endIndex) {
    const midIndex = Math.floor((endIndex + startIndex) / 2)
    const midValue = arr[midIndex]
    if (target < midValue) {
      endIndex = midIndex - 1 // 目标值较小,继续在左侧查找
    } else if (target > midValue) {
      startIndex = midIndex + 1 // 目标值较大,继续在右侧查找
    } else {
      // 相等,返回
      return midIndex
    }
  }
  return -1
}

递归实现

function binarySearch2(arr: number[], target: number, startIndex?: number, endIndex?: number): number {
  if (arr.length === 0) return -1
  if (startIndex == null) {
    startIndex = 0
  }
  if (endIndex == null) {
    endIndex = arr.length - 1
  }
  if (startIndex > endIndex) return -1
  let midIndex = Math.floor((startIndex + endIndex) / 2)
  let midValue = arr[midIndex]
  if (target < midValue) {
    return binarySearch2(arr, target, startIndex, midIndex - 1)
  } else if (target > midValue) {
    return binarySearch2(arr, target, midIndex + 1, endIndex)
  } else {
    return midIndex
  }
}

// 功能测试
const ar1 = [10, 20, 30, 40, 50, 60]
const target = 20
console.log(binarySearch1(ar1, target))
console.log(binarySearch2(ar1, target))

性能测试


// 性能测试
console.time('binarySearch1')
for (let i = 0; i < 100 * 10000; i++){
  binarySearch1(ar1,target)
}
console.timeEnd('binarySearch1') // 22ms
console.time('binarySearch2')
for (let i = 0; i < 100 * 10000; i++) {
  binarySearch2(ar1, target)
}
console.timeEnd('binarySearch2') //40ms

划重点

  • 凡有序,必二分
  • 凡二分,时间复杂度必然包含O(logn)