【前端算法】javaScript实现二分查找

简介: 如何使用JS实现一个合格的二分查找

JS实现二分查找

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

代码实现 —— 循环

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

  let startIdx = 0 // 开始位置
  let endIdx = len - 1 // 结束位置

  while (startIdx <= endIdx) {
    let midIdx = Math.floor((startIdx + endIdx) / 2)
    let midVal = arr[midIdx] // 中间值

    if (sval < midVal) {
      // 小于中间值,继续在左侧寻找
      endIdx = midIdx - 1
    } else if (sval > midVal) {
      // 大于中间值,继续在右侧寻找
      startIdx = midIdx + 1
    } else {
      // 等于中间值
      return midIdx
    }
  }
  return -1
}

代码实现 —— 递归

function binarySearch2(arr: number[],target: number, startIdx?: number, endIdx?: number): number {
  const len = arr.length
  if (len === 0) return -1

  // 初始化边界
  if (typeof startIdx !== 'number') startIdx = 0
  if (typeof endIdx !== 'number') endIdx = len - 1

  const midIdx = Math.floor((startIdx + endIdx) / 2)

  if (startIdx > endIdx) return -1
  // 开始比较
  if (target < arr[midIdx]) {
    // 小于中间值,继续在左侧寻找
    return binarySearch2(arr, target, startIdx, midIdx - 1)
  } else if (target > arr[midIdx]) {
    // 大于中间值,继续在右侧寻找
    return binarySearch2(arr, target, midIdx + 1, endIdx)
  } else {
    // 等于中间值
    return midIdx
  }
}

功能测试

const arr = [1, 4, 6, 8, 9, 11, 14, 19, 21, 22, 31, 32, 35, 36, 40, 50, 80, 100, 120]
const res:number = binarySearch1(arr,9) // 4
const res:number = binarySearch2(arr,9) // 4

单元测试

describe('二分查找' , () => {
  it('正常情况',() => {
    const arr = [1, 4, 6, 8, 9, 11, 14, 19, 21, 22, 31, 32, 35, 36, 40, 50, 80, 100, 120]
    const res:number = binarySearch1(arr,9)
    expect(res).toBe(4)
  })

  it('空数组', () => {
    const res:number = binarySearch1([],9)
    expect(res).toBe(-1)
  })

  it('找不到 target', () => {
    const arr = [1, 4, 6, 8, 9, 11, 14, 19, 21, 22, 31, 32, 35, 36, 40, 50, 80, 100, 120]
    const res:number = binarySearch1(arr,51)
    expect(res).toBe(-1)
  })
})

性能比较

const arr = [1, 4, 6, 8, 9, 11, 14, 19, 21, 22, 31, 32, 35, 36, 40, 50, 80, 100, 120]
console.time('binarySearch1')
for (let j = 0; j < 100 * 10000; j++) {
  const res = binarySearch1(arr, 50)
}

console.timeEnd('binarySearch1')

console.time('binarySearch2')
for (let j = 0; j < 100 * 10000; j++) {
  const res = binarySearch2(arr, 50)
}

console.timeEnd('binarySearch2')

打印结果

binarySearch1: 15.719ms
binarySearch2: 33.577ms

由此可见循环的二分比递归的二分,性能更佳,但是递归语义更容易理解,所以常用的还是递归!

相关文章
|
4天前
|
JavaScript 前端开发 开发者
Vue.js 框架大揭秘:响应式系统、组件化与路由管理,震撼你的前端世界!
【8月更文挑战第27天】Vue.js是一款备受欢迎的前端JavaScript框架,以简洁、灵活和高效著称。本文将从三个方面深入探讨Vue.js:响应式系统、组件化及路由管理。响应式系统为Vue.js的核心特性,能自动追踪数据变动并更新视图。例如,通过简单示例代码展示其响应式特性:`{{ message }}`,当`message`值改变,页面随之自动更新。此外,Vue.js支持组件化设计,允许将复杂界面拆分为独立且可复用的组件,提高代码可维护性和扩展性。如创建一个包含标题与内容的简单组件,并在其他页面中重复利用。
22 3
|
2天前
|
JavaScript 算法 前端开发
JS算法必备之String常用操作方法
这篇文章详细介绍了JavaScript中字符串的基本操作,包括创建字符串、访问特定字符、字符串的拼接、位置查找、大小写转换、模式匹配、以及字符串的迭代和格式化等方法。
JS算法必备之String常用操作方法
|
2天前
|
JavaScript 算法 前端开发
JS算法必备之Array常用操作方法
这篇文章详细介绍了JavaScript中数组的创建、检测、转换、排序、操作方法以及迭代方法等,提供了数组操作的全面指南。
JS算法必备之Array常用操作方法
|
1天前
|
JavaScript 前端开发 API
揭秘现代前端开发秘籍:Vue.js与ES6如何联手打造惊艳应用?
【8月更文挑战第30天】本文介绍如何从零开始使用Vue.js与ES6创建现代前端应用。首先,通过简要介绍Vue.js和ES6的新特性,使读者了解这两者为何能有效提升开发效率。接着,指导读者使用Vue CLI初始化项目,并展示如何运用ES6语法编写Vue组件。最后,通过运行项目验证组件功能,为后续开发打下基础。适用于希望快速入门Vue.js与ES6的前端开发者。
11 3
|
4天前
|
Rust 前端开发 JavaScript
震惊!JavaScript 与 WebAssembly 强强联合,开启前端性能传奇之旅,你准备好了吗?
【8月更文挑战第27天】在互联网飞速发展的今天,前端技术,特别是核心语言JavaScript,正经历着持续的革新。为了突破JavaScript在处理复杂计算时的性能局限,WebAssembly应运而生。作为一种高效的二进制格式,WebAssembly能以接近原生的速度在浏览器中运行,支持C、C++和Rust等语言编写的高性能代码。它与JavaScript相辅相成,前者专注于高性能计算任务(如游戏开发、图像处理),后者则负责页面的交互与逻辑控制。通过结合使用,二者为前端开发者提供了更为强大和灵活的工具集,共同推动前端技术进入一个全新的性能时代。
13 2
|
4天前
|
缓存 前端开发 JavaScript
超时空加速秘籍:揭秘JavaScript前端开发中的性能魔法,让您的Web应用瞬间穿越到未来!
【8月更文挑战第27天】本文介绍了一系列实用的JavaScript性能优化方法并提供了示例代码,包括减少DOM操作、使用事件委托、避免阻塞主线程、异步加载资源、利用浏览器缓存、代码分割以及使用Service Worker等技术,帮助开发者有效提升Web应用性能和用户体验。
18 2
|
3天前
|
JavaScript 前端开发 小程序
【技巧】JS代码这么写,前端小姐姐都会爱上你
本文介绍了JavaScript编程中的实用技巧,包括解构赋值的多种妙用、数组操作技巧及常用JS功能片段。解构赋值部分涵盖短路语法防错、深度解构及默认值赋值;数组技巧包括按条件添加数据、获取最后一个元素及使用`includes`优化`if`语句;常用功能片段则涉及URL参数解析、页面滚动回顶部及获取滚动距离等。通过这些技巧,提升代码质量和效率。
13 0
【技巧】JS代码这么写,前端小姐姐都会爱上你
|
8天前
|
前端开发 JavaScript
Web 前端大揭秘!JS 数据类型检测竟如此震撼,一场惊心动魄的代码探秘之旅等你来!
【8月更文挑战第23天】在Web前端开发中,合理检测数据类型至关重要。JavaScript作为动态类型语言,变量类型可在运行时变化,因此掌握检测技巧十分必要。
17 1
|
1天前
|
JavaScript 前端开发 开发者
Vue.js的未来已来:掌握最新功能,驾驭前端开发的新浪潮!
【8月更文挑战第30天】Vue.js作为前端开发领域的明星框架,凭借其轻量级、响应式及组件化特性,深受全球开发者喜爱。它持续进化,引入新功能并优化性能,如提升渲染速度和减小打包体积,增强TypeScript支持,简化组件编写流程,进一步提升应用响应性和加载速度,改善开发者体验。活跃的社区和丰富的开源项目如“vuejs-challenges”推动其不断发展。未来,Vue.js将探索更多新特性,如宏和非虚拟DOM模式,巩固其在现代前端框架中的领先地位。
|
1天前
|
JavaScript 前端开发 测试技术
Vue.js开发者必看!Vue Test Utils携手端到端测试,打造无懈可击的应用体验,引领前端测试新风尚!
【8月更文挑战第30天】随着Vue.js的普及,构建可靠的Vue应用至关重要。测试不仅能确保应用质量,还能提升开发效率。Vue Test Utils作为官方测试库,方便进行单元测试,而结合端到端(E2E)测试,则能构建全面的测试体系,保障应用稳定性。本文将带你深入了解如何使用Vue Test Utils进行单元测试,通过具体示例展示如何测试组件行为;并通过Cypress进行E2E测试,确保整个应用流程的正确性。无论是单元测试还是E2E测试,都能显著提高Vue应用的质量,让你更加自信地交付高质量的应用。
下一篇
云函数