博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据结构与算法:二分查找
阅读量:6157 次
发布时间:2019-06-21

本文共 2426 字,大约阅读时间需要 8 分钟。

图片描述

二分查找是搜索算法中的一种,用来搜索有序数组

二分查找: 是一种简单算法,其输入是一个有序的元素列表(必须有序的原因稍后解释)。如果要

查找的元素包含在列表中,二分查找返回其位置;否则返回null

Javascript ES6实现

非递归的

/**  * 函数binarySearch接受一个有序数组和一个元素。 如果指定的元素包含在数组中, 这个 函数将返回其位置。 你将跟踪要在其中查找的数组部分—— 开始时为整个数组。*/const binarySearch = (list, item) => {  // 数组要查找的范围  // low、high用于跟踪要在其中查找的列表部分  let low = 0    let high = list.length - 1  while(low <= high) { // 只要范围没有缩小到只包含一个元素    const mid = Math.floor((low + high) / 2)    const guess = list[mid] // 找到中间的元素    if(guess === item) { // 找到元素      return mid    }    if(guess > item) { // 猜测的数大了      high = mid - 1    } else { // 猜测的数小了      low = mid + 1    }  }  return null}const myList = [1, 3, 5, 7, 9]console.log(binarySearch(myList, 3))console.log(binarySearch(myList, -1))

递归的

const binarySearch = (list, item, low, hight) => {  let arrLength = list.length  while (low <= high) {    let mid = Math.floor((low + high) / 2)    let guess = list[mid]    if( guess === item ) {      return mid    } else if (guess > item) {      high = mid - 1      list = list.slice(0, mid)      return binarySearch(list, item, low, high)    } else {      low = mid + 1      list = list.slice(low, arrLength)      return binarySearch(list, item, low, high)    }  }  return null }const createArr = (n) => Array.from({length: n}, (v, k) => k + 1)const myList = createArr(100)let low = 0let high = myList.length - 1console.log(binarySearch(myList, 3, low, high))console.log(binarySearch(myList, -1, low, high))

Python实现

运行时间(时间复杂度)

图片描述

二分查找的运行时间为对数时间(或log时间)。

如果列表包含100个元素,最多要猜7次;如果列表包含40亿个数字,最多
需猜32次。
图片描述
即: 2的7次方 = 100

图片描述

简单查找时间是 y= ax 的线性方方程
所以很容易得出结论

随着元素数量的增加(x增加),二分查找需要的时间(y)并不多, 而简单查找需要的时间(y)却很多。
因此,随着列表的增长,二分查找的速度比简单查找快得多。

为检查长度为n的列表,二分查找需要执行log n次操作。使用大O表示法,

这个运行时间怎么表示呢?O(log n)。一般而言,简单算法的大O表示法像下面这样
图片描述

clipboard.png

大O符号

大O符号中指定的算法的增长顺序

图片描述

以下是一些最常用的 大O标记法 列表以及它们与不同大小输入数据的性能比较。

图片描述

  • O(log n),也叫对数时间,这样的算法包括二分查找
  • O(n),也叫线性时间,这样的算法包括简单查找。
  • O(n * log n),这样的算法包括快速排序——一种速度较快的排序算法。
  • 图片描述,这样的算法包括选择排序——一种速度较慢的排序算法
  • O(n!),这样的算法包括接下来将介绍的旅行商问题的解决方案——一种非常慢的算法

图片描述

小结

  • 算法的速度指的并非时间,而是操作数的增速。
  • 谈论算法的速度时,我们说的是随着输入的增加,其运行时间将以什么样的速度增加。
  • 算法的运行时间用大O表示法表示。
  • O(log n)比O(n)快,当需要搜索的元素越多时,前者比后者快得越多

 旅行商问题--复杂度O(n!)的算法

简单的讲如果旅行者要去5个城市,先后顺序确定有5*4*3*2*1 = 120种排序。(这种排序想想高中时候学到过的排序知识)

推而广之,涉及n个城市时,需要执行n!(n的阶乘)次操作才能计算出结果。因此运行时间
为O(n!),即阶乘时间。除非涉及的城市数很少,否则需要执行非常多的操作。如果涉及的城市
数超过100,根本就不能在合理的时间内计算出结果——等你计算出结果,太阳都没了。

这种算法很糟糕!,可别无选择。这是计算机科学领域待解的问题之一。对于这个问题,目前还没有找到更快的算法,有些很聪明的人认为这个问题根本就没有更巧妙的算法。

面对这个问题,我们能做的只是去找出近似答案。

最后需要指出的一点是,高水平的读者可研究一下二叉树

关于二叉树,戳这里:

参考

转载地址:http://xnsfa.baihongyu.com/

你可能感兴趣的文章
php入门篇------->PHPCMS 入口文件,自动加载系统函数和URL规则
查看>>
Mybatis 源码解析 -- 基于配置的源码解析(二)
查看>>
创新工场CE0李开复:互联网创业黄金时代来临
查看>>
KeyMob:我们做的不仅是移动广告聚合 更是靠谱
查看>>
linux下find命令之-exec ll -sh {} \;
查看>>
Solr Facet 查询
查看>>
C++类的继承一
查看>>
数据库分库分表(sharding)系列(五) 一种支持自由规划无须数据迁移和修改路由代码的Sharding扩容方案...
查看>>
巧用VMware Workstation的clone来制作虚拟机模板
查看>>
Spring-Mybatis MapperScannerConfigurer 取不到PropertyPlaceholderConfigurer里的值
查看>>
HP DL380G4服务器前面板指示灯的含义
查看>>
数据结构_树结构
查看>>
常用URL地址
查看>>
每天一个linux命令(19):find 命令概览
查看>>
MySQL kill操作
查看>>
windows下看端口占用
查看>>
Decommissioning a Domain Controller 降域控
查看>>
Character中的奇葩
查看>>
c++书籍推荐
查看>>
Exception在语义上的处理。在系统中的意义。
查看>>