成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面試官:說說你對二分查找的理解?如何實(shí)現(xiàn)?應(yīng)用場景?

開發(fā) 前端
在計(jì)算機(jī)科學(xué)中,二分查找算法,也稱折半搜索算法,是一種在有序數(shù)組中查找某一特定元素的搜索算法。

[[428826]]

本文轉(zhuǎn)載自微信公眾號「JS每日一題」,作者灰灰。轉(zhuǎn)載本文請聯(lián)系JS每日一題眾號。

一、是什么

在計(jì)算機(jī)科學(xué)中,二分查找算法,也稱折半搜索算法,是一種在有序數(shù)組中查找某一特定元素的搜索算法

想要應(yīng)用二分查找法,則這一堆數(shù)應(yīng)有如下特性:

  • 存儲在數(shù)組中
  • 有序排序

搜索過程從數(shù)組的中間元素開始,如果中間元素正好是要查找的元素,則搜索過程結(jié)束

如果某一特定元素大于或者小于中間元素,則在數(shù)組大于或小于中間元素的那一半中查找,而且跟開始一樣從中間元素開始比較

如果在某一步驟數(shù)組為空,則代表找不到

這種搜索算法每一次比較都使搜索范圍縮小一半

如下圖所示:

相比普通的順序查找,除了數(shù)據(jù)量很少的情況下,二分查找會比順序查找更快,區(qū)別如下所示:

二、如何實(shí)現(xiàn)

基于二分查找的實(shí)現(xiàn),如果數(shù)據(jù)是有序的,并且不存在重復(fù)項(xiàng),實(shí)現(xiàn)代碼如下:

  1. function BinarySearch(arr, target) { 
  2.     if (arr.length <= 1) return -1 
  3.     // 低位下標(biāo) 
  4.     let lowIndex = 0 
  5.     // 高位下標(biāo) 
  6.     let highIndex = arr.length - 1 
  7.  
  8.     while (lowIndex <= highIndex) { 
  9.         // 中間下標(biāo) 
  10.         const midIndex = Math.floor((lowIndex + highIndex) / 2) 
  11.         if (target < arr[midIndex]) { 
  12.             highIndex = midIndex - 1 
  13.         } else if (target > arr[midIndex]) { 
  14.             lowIndex = midIndex + 1 
  15.         } else { 
  16.             // target === arr[midIndex] 
  17.             return midIndex 
  18.         } 
  19.     } 
  20.     return -1 

如果數(shù)組中存在重復(fù)項(xiàng),而我們需要找出第一個(gè)制定的值,實(shí)現(xiàn)則如下:

  1. function BinarySearchFirst(arr, target) { 
  2.     if (arr.length <= 1) return -1 
  3.     // 低位下標(biāo) 
  4.     let lowIndex = 0 
  5.     // 高位下標(biāo) 
  6.     let highIndex = arr.length - 1 
  7.  
  8.     while (lowIndex <= highIndex) { 
  9.         // 中間下標(biāo) 
  10.         const midIndex = Math.floor((lowIndex + highIndex) / 2) 
  11.         if (target < arr[midIndex]) { 
  12.             highIndex = midIndex - 1 
  13.         } else if (target > arr[midIndex]) { 
  14.             lowIndex = midIndex + 1 
  15.         } else { 
  16.             // 當(dāng) target 與 arr[midIndex] 相等的時(shí)候,如果 midIndex 為0或者前一個(gè)數(shù)比 target 小那么就找到了第一個(gè)等于給定值的元素,直接返回 
  17.             if (midIndex === 0 || arr[midIndex - 1] < target) return midIndex 
  18.             // 否則高位下標(biāo)為中間下標(biāo)減1,繼續(xù)查找 
  19.             highIndex = midIndex - 1 
  20.         } 
  21.     } 
  22.     return -1 

實(shí)際上,除了有序的數(shù)組可以使用,還有一種特殊的數(shù)組可以應(yīng)用,那就是輪轉(zhuǎn)后的有序數(shù)組

有序數(shù)組即一個(gè)有序數(shù)字以某一個(gè)數(shù)為軸,將其之前的所有數(shù)都輪轉(zhuǎn)到數(shù)組的末尾所得

例如,[4, 5, 6, 7, 0, 1, 2]就是一個(gè)輪轉(zhuǎn)后的有序數(shù)組

該數(shù)組的特性是存在一個(gè)分界點(diǎn)用來分界兩個(gè)有序數(shù)組,如下:

分界點(diǎn)有如下特性:

  • 分界點(diǎn)元素 >= 第一個(gè)元素
  • 分界點(diǎn)元素 < 第一個(gè)元素

代碼實(shí)現(xiàn)如下:

  1. function search (nums, target) { 
  2.   // 如果為空或者是空數(shù)組的情況 
  3.   if (nums == null || !nums.length) { 
  4.     return -1; 
  5.   } 
  6.   // 搜索區(qū)間是前閉后閉 
  7.   let begin = 0, 
  8.     end = nums.length - 1; 
  9.   while (begin <= end) { 
  10.     // 下面這樣寫是考慮大數(shù)情況下避免溢出 
  11.     let mid = begin + ((end - begin) >> 1); 
  12.     if (nums[mid] == target) { 
  13.       return mid; 
  14.     } 
  15.     // 如果左邊是有序的 
  16.     if (nums[begin] <= nums[mid]) { 
  17.       //同時(shí)target在[ nums[begin],nums[mid] ]中,那么就在這段有序區(qū)間查找 
  18.       if (nums[begin] <= target && target <= nums[mid]) { 
  19.         end = mid - 1; 
  20.       } else { 
  21.         //否則去反方向查找 
  22.         begin = mid + 1; 
  23.       } 
  24.       //如果右側(cè)是有序的 
  25.     } else { 
  26.       //同時(shí)target在[ nums[mid],nums[end] ]中,那么就在這段有序區(qū)間查找 
  27.       if (nums[mid] <= target && target <= nums[end]) { 
  28.         begin = mid + 1; 
  29.       } else { 
  30.         end = mid - 1; 
  31.       } 
  32.     } 
  33.   } 
  34.   return -1; 
  35. }; 

對比普通的二分查找法,為了確定目標(biāo)數(shù)會落在二分后的哪個(gè)部分,我們需要更多的判定條件

三、應(yīng)用場景

二分查找法的O(logn)讓它成為十分高效的算法。不過它的缺陷卻也是比較明顯,就在它的限定之上:

有序:我們很難保證我們的數(shù)組都是有序的

數(shù)組:數(shù)組讀取效率是O(1),可是它的插入和刪除某個(gè)元素的效率卻是O(n),并且數(shù)組的存儲是需要連續(xù)的內(nèi)存空間,不適合大數(shù)據(jù)的情況

關(guān)于二分查找的應(yīng)用場景,主要如下:

不適合數(shù)據(jù)量太小的數(shù)列;數(shù)列太小,直接順序遍歷說不定更快,也更簡單

每次元素與元素的比較是比較耗時(shí)的,這個(gè)比較操作耗時(shí)占整個(gè)遍歷算法時(shí)間的大部分,那么使用二分查找就能有效減少元素比較的次數(shù)

不適合數(shù)據(jù)量太大的數(shù)列,二分查找作用的數(shù)據(jù)結(jié)構(gòu)是順序表,也就是數(shù)組,數(shù)組是需要連續(xù)的內(nèi)存空間的,系統(tǒng)并不一定有這么大的連續(xù)內(nèi)存空間可以使用

參考文獻(xiàn)

https://zh.wikipedia.org/wiki/%E4%BA%8C%E5%88%86%E6%90%9C%E5%B0%8B%E6%BC%94%E7%AE%97%E6%B3%95#javascript_%E7%89%88%E6%9C%AC

 

https://www.cnblogs.com/ider/archive/2012/04/01/binary_search.html

 

責(zé)任編輯:武曉燕 來源: JS每日一題
相關(guān)推薦

2021-09-28 07:12:09

測試路徑

2021-09-29 07:24:20

場景數(shù)據(jù)

2021-09-16 07:52:18

算法應(yīng)用場景

2021-10-13 18:01:33

快速排序場景

2021-10-08 09:59:32

冒泡排序場景

2021-10-09 10:25:41

排序應(yīng)用場景

2021-11-05 07:47:56

代理模式對象

2021-11-09 08:51:13

模式命令面試

2021-11-10 07:47:49

組合模式場景

2021-11-03 14:10:28

工廠模式場景

2021-08-16 08:33:26

git

2021-10-11 09:38:41

開源

2021-10-12 07:15:02

歸并排序場景

2021-09-06 10:51:27

TypeScriptJavaScript

2021-11-11 16:37:05

模板模式方法

2021-11-22 23:50:59

責(zé)任鏈模式場景

2021-09-10 06:50:03

TypeScript裝飾器應(yīng)用

2021-09-08 07:49:34

TypeScript 泛型場景

2021-11-04 06:58:32

策略模式面試

2021-06-01 08:25:06

Node.jsJavaScript運(yùn)行
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 国产一区不卡 | 81精品国产乱码久久久久久 | 91网站视频在线观看 | 国产乱码精品一区二区三区中文 | 精品无码久久久久久久动漫 | 日韩不卡三区 | 午夜免费观看体验区 | 操人网 | 九九综合 | 亚洲精品乱码 | 亚洲美女视频 | 亚洲高清在线免费观看 | 一区二区三区视频在线观看 | 成人在线视频观看 | 亚洲播放一区 | 91精品国产91综合久久蜜臀 | 久久新 | 综合一区二区三区 | 国产精品免费视频一区 | 亚洲欧美一区在线 | 男人天堂网址 | 99精品欧美一区二区三区综合在线 | 国产精品一区二区在线 | 成人久久久 | 中文字幕精品一区二区三区精品 | 成人欧美一区二区三区黑人孕妇 | 天天干天天插天天 | 国产精品久久久久久 | 亚洲免费在线视频 | 激情91 | 中文字幕视频一区二区 | 日韩美女爱爱 | 日韩欧美在线视频 | 久久高清| 国产精品av久久久久久毛片 | 国产精品久久久久久久久免费软件 | 精品在线一区二区三区 | 欧美精品在线观看 | 国产一区二区三区四区区 | 久久久久久久久久久蜜桃 | 九九精品影院 |