二分查找

2021-03-03 TanLiuYi00
二分查找又稱折半查找(Binary Search),是一種效率較高的查找方法。前提

線性表採用順序存儲結構,線性表中的元素是有序排列的。

基本思路

假設線性表中的元素是按升序排列的,先將待查找的區間分成兩部分,即[low, mid) 和 (mid, high] ,查找過程從線性表的中間元素開始,如果中間元素恰好是要查找的元素,則結束查找;如果中間元素大於要查找的元素,則在前半區間 [low, mid) 中查找;否則就在後半區間(mid, high] 中查找;而且跟開始一樣先從中間元素開始比較,直到找到要查找的元素或者線性表中不存在該元素(查找區間最後為空)。

舉慄

給定一個有序數組:[0, 5, 6, 9, 12, 15, 18, 20, 23],查找target:6

查找過程如下:

由於nums[mid] = 12 > target = 6, 則到mid的前半區間[low, mid)中查找,high = mid - 1 = 3,mid = (low + high) / 2 = 1。

此時nums[mid] = 5 < target = 6,則到mid的後半區間(mid, high] 中查找,low = mid + 1 = 2, mid = (low + high) / 2 = 2。

這時nums[mid] = 6 == target = 6,找到目標元素,查找結束。

二分查找模板

非遞歸版本

int binarySearch(int* nums, int numsSize, int target) {    if (nums == NULL || numsSize <= 0) {        return -1;    }     int low = 0, high = numsSize - 1;        while (low <= high) {                                       int mid = low + ((high - low) >> 1);                    if (nums[mid] == target) {                        return mid;                         } else if (nums[mid] > target) {                  high = mid - 1;                  } else if (nums[mid] < target) {                    low = mid + 1;                              }    }     return -1;}

遞歸版本

int binarySearch(int* nums, int low, int high, int target) {    if (low > right) {        return -1;    }     int mid = low + (high - low) / 2;    if (nums[mid] > target) {        return binarySearch(nums, low, mid - 1, target);    } else if (nums[mid] < target) {        return binarySearch(nums, mid + 1, high, target);    }  else if (nums[mid] == target) {        return mid;    }    }

注意點

mid 為何取 low + ((high - low) >> 1) 或者 low + (high - low) / 2 而不是 (high + low) / 2 ?
因為 int 類型最大表示範圍是 2147483647 ,那麼對於兩個都接近 2147483647 的數字而言,它們相加的結果將會溢出,變成負數。所以為了避免出現整數溢出的風險,使用前面兩個替代。

while 循環何時終止?
當搜索區間為空或者目標元素找到,就結束循環。
while (low <= high) 終止條件是 low == high + 1 ,即[high + 1, high],此時搜索區間為空,結束循環。

 

相關焦點

  • 二分查找和插值查找
    二分查找就是:在一組數據中取出中間的那個元素,將其和要找的元素對比,如果不是要找的元素,則以其為標記點,將這組數據分成兩半,取出符合條件的一半遞歸進行如上操作直到找出數據為止。二分查找的複雜度為O(logN),在數據量小的情況下這兩種查找算法的效率相差無幾,但是在數據量很大的情況下,二分查找的性能就遠遠高於順序查找了。
  • 二分查找算法案列詳解
    1、前言最近刷了很多二分查找相關的題目,這裡將近期的收穫做一個總結,包括二分查找的變形問題。如果能掌握,我相信以後基本上二分查找相關的問題對你來說,都不是問題。2、二分查找的效率二分查找是啥我想不用過多的說明。
  • 二分查找的妙用:判定子序列
    二分查找本身不難理解,難在巧妙地運用二分查找技巧。對於一個問題,你可能都很難想到它跟二分查找有關,比如前文 最長遞增子序列就藉助一個紙牌遊戲衍生出二分查找解法。今天再講一道巧用二分查找的算法問題:如何判定字符串s是否是字符串t的子序列(可以假定s長度比較小,且t的長度非常大)。
  • 二分查找算法及其應用
    二分查找也稱折半查找(Binary Search),它是一種效率較高的查找方法。
  • 算法入門——二分查找法
    二分查找法      假設我們要在一個電話簿中查找一個名字為g名字開頭的人,我們可以從頭開始翻頁
  • 二分查找和大O表示法
    這種查找方式是----二分查找。二分查找的方法如下:        ①猜想的數字是0-100,那麼先從0-100的中間數 50 開始,則會有如下結論:50雖然小了,但是我們排除了0-50的數字。代碼實現:       編寫執行二分查找的python代碼,代碼示例使用數組(在python中叫做列表)        tips:1、給出的序列必須有序,才可以進行二分查找                 2、在python3中,/表示浮點數除法,//表示整數除法
  • 二分查找,沒那麼簡單!
    今天討論,二分查找二分查找注意事項二分查找表面看似很簡單,就是對解空間的不斷二分,直至逼近解並返回。但是實操起來,卻絕非這麼簡單。要首先分析出對誰折半,有些問題顯而易見,如有序數組查某個數的位置,因為索引值越大,元素值就越大,所以對索引範圍折半。
  • Leetcode刷題-二分查找
    本文對部分涉及二分查找算法的leetcode題目進行了學習與實踐,並給出了個人的二分查找python模板二分查找算法解釋二分查找算法(英語:binary search algorithm),也稱折半搜索算法(英語:half-interval search algorithm
  • 聊聊一看就會一寫就跪的二分查找
    要說哪個算法的知名度較高,二分查找一定排得上號。後來我又在維基百科上發現了這樣一段話:儘管二分查找的基本思想相對簡單,但細節可以令人難以招架 —— 高德納當喬恩·本特利將二分查找問題布置給專業編程課的學生時,90%的學生在花費數小時後還是無法給出正確的解答,主要因為這些錯誤程序在面對邊界值的時候無法運行,或返回錯誤結果。1988年開展的一項研究顯示,20本教科書裡只有5本正確實現了二分查找。
  • Python 的二分查找法,聽說你還不知道是啥?
    點擊上方藍字,關注:無量測試之道    作者 | 無量測試之道   編輯 | 小 晴今天分享的主題內容是:二分查找法。Python 中與除法相關的三個運算符是// 和 / 和 %:「/」,這是傳統的除法,5/2=2.5「//」,在Python 中,這個叫「地板除」,9//4=2「%」,這個是取模操作,也就是取餘數,4%2=0,5%2=11、什麼是二分查找法    二分查找也稱折半查找
  • 一文帶你從代碼的角度詳細搞懂什麼是二分查找樹
    一、二分查找二分查找應該應熟悉了吧?要在順序儲存結構中進行查找,跟最中間的數據進行比較,小的話去前半部分進行查找,否則,去後半部分去查找,其實,可以用迭代和遞歸分別來實現二分查找。1、迭代法  首先,用迭代法來實現,代碼如下:// 二分查找法,在有序數組arr中,查找target// 如果找到target,返回相應的索引index// 如果沒有找到target,返回-1
  • 六十八、快速冪算法、牛頓迭代法、累加數組+二分查找的變形
    「---- Runsen」❞上次介紹了二分查找算法及其四個變形問題,下面介紹二分法常用的場景和典型的例題。快速冪算法題目是來自Leetcode:50.觀察發現,當 n 為奇數時,二分後會多出一項 x 。比如:。
  • 「二分查找」面試最常考題
    解法二:在 O(n) 的基礎上我們還想優化,那方向是 O(logn),再想想查找類算法的很容易想到了 binary search。binary search 的做法就是每輪排除一半,留下另一半是包含正確答案的,再不斷縮小範圍,把答案找出來。那麼解決的關鍵就在於如何殺掉這一半而不能把答案誤殺了。
  • 數據結構:查找(1)||靜態順序查找表、靜態有序查找表
    查找行為就是根據某個值找到查找表中關鍵字等於所給值的記錄或元素。若能找到則稱查找成功,找不到則是查找不成功。靜態查找表靜態查找表不具備第三個功能,即插入和刪除。有序表的查找二分查找已經不是第一次接觸到。對於有序表,可以採用二分查找的辦法快速完成查找。
  • 原來Kafka源碼也在用二分搜索!
    4 二分查找算法到目前為止,從已排序數組中尋找某個數字最快速的算法就是二分查找了,它能做到O(lgN)的時間複雜度。Kafka的索引組件就應用了二分查找算法。Kafka索引應用二分查找算法快速定位待查找索引項位置,之後調用parseEntry來讀取索引項。
  • 「二分查找」之我見!今天刷一道leetcode算法!
    解法二:在 O(n) 的基礎上我們還想優化,那方向是 O(logn),再想想查找類算法的很容易想到了 binary search。binary search 的做法就是每輪排除一半,留下另一半是包含正確答案的,再不斷縮小範圍,把答案找出來。那麼解決的關鍵就在於如何殺掉這一半而不能把答案誤殺了。
  • 你真的理解二分的寫法嗎?
    說實話,我之前也不完全理解二分查找的各種寫法,導致在寫各種二分的邊界時我總是弄不清邊界值,於是我只能通過暴力枚舉這些邊界值,去一個一個試,這樣子效率真的很低下。於是,痛定思痛,一定要把二分的寫法吃透,就有了這篇文章。二分寫法的種類二分寫法的種類很多,最常見的就是二分查找了的最普遍寫法了。
  • 圖解:三款經典的查找算法,等著你
    跳躍查找(Jump Search)與二分查找類似,跳躍查找也是在有序數組上進行的。基本思想是以固定步長向前跳越,從而跳過儘可能多的不在待查找元素附近的元素,減少查找過程中的比較次數。二分查找比跳躍查找的時間複雜度更低,但是跳躍查找的優勢在於僅需要回溯一次(即線性遍歷的部分),而在搜索數組中最小的元素或者最大元素的情況下,二分查找需要回溯多次。因此,在二分查找成本很高的時候,我們可以考慮跳躍查找。
  • 七大查找算法
    本文簡單概括性的介紹了常見的七種查找算法,說是七種,其實二分查找、插值查找以及斐波那契查找都可以歸為一類——插值查找。插值查找和斐波那契查找是在二分查找的基礎上的優化查找算法。樹表查找和哈希查找會在後續的博文中進行詳細介紹。  查找定義:根據給定的某個值,在查找表中確定一個其關鍵字等於給定值的數據元素(或記錄)。
  • 方法的查找流程——慢速查找
    想必大家已經對方法的查找流程有過基本的了解了,所以這個例子大家應該都能理解,接下來我們就從源碼層面來分析方法的慢速查找流程。方法的慢速查找流程分析在上篇文章方法的查找流程——快速查找中,我們知道,在緩存中沒有查找到對應的方法之後,最終會走到_class_lookupMethodAndLoadCache3函數,今天我們就從該函數開始入手研究。