11.二分查找的實現(xiàn)與特性

11.二分查找的實現(xiàn)與特性

二分查找的前提

  1. 目標函數(shù)單調(diào)性(單調(diào)遞增或者遞減)
  2. 存在上下界(bounded)
  3. 能夠通過索引訪問(index accessible)

這三個前提條件的話簡單說來,一定要把它形成肌肉式記憶。

  • 第一單調(diào)性:二分查找的是在有序的里面進行查找齐邦,如果它是無序的話記憶沒法進行二分查找析恋,無序的話怎么辦呢?只能從頭到尾遍歷,正因為它是有序的,所以能夠通過判斷它的某些特征排除掉比如說前半部分或者排除掉后半部分,所以這里它必須是要單調(diào)的到涂。
  • 第二上下界:存在一個上下界,如果沒有上下界的話颁督,那么它的空間可能是無窮大的践啄,那么它就沒法往中間擴,當然也有特殊的形態(tài)沉御。
  • 第三索引:索引的話指的是可以用下標進行訪問屿讽,所以很多時候如果是單鏈表的話,相對來說即使是有序的吠裆,單鏈表進行二分查找都不是那么容易的伐谈,當然如果把單鏈表進行一些改造,比如說用它所謂的跳表的方式试疙,那就另當別說了诵棵。

代碼模版

// Java
public int binarySearch(int[] array, int target) {
    int left = 0, right = array.length - 1, mid;
    while (left <= right) {
        mid = (right - left) / 2 + left;

        if (array[mid] == target) {
            return mid;
        } else if (array[mid] > target) {
            right = mid - 1;
        } else {
            left = mid + 1;
        }
    }

    return -1;
}
# Python
left, right = 0, len(array) - 1 
while left <= right: 
      mid = (left + right) / 2 
      if array[mid] == target: 
            # find the target!! 
            break or return result 
      elif array[mid] < target: 
            left = mid + 1 
      else: 
            right = mid - 1
C/C++

int binarySearch(const vector<int>& nums, int target) {
    int left = 0, right = (int)nums.size()-1;
    
    while (left <= right) {
        int mid = left + (right - left)/ 2;
        if (nums[mid] == target) return mid;
        else if (nums[mid] < target) left = mid + 1;
        else right = mid - 1;
    }
    
    return -1;
}
/* JavaScript */
let left = 0, right = len(array) - 1
while (left <= right) {
  let mid = (left + right) >> 1
  if (array[mid] === target) { /*find the target*/; return }
  else if (array[mid] < target) left = mid + 1
  else right = mid - 1
}

首先左右界,分別是 0數(shù)組長度減1祝旷,也就是左右的下標值履澳,這個毋庸置疑嘶窄,while 的話里面是 left 小于等于 right 所以這個條件的話有些時候會變成沒有等于號,但是大部分情況下你可以認為是有小于等于的距贷。

然后得到它的中間值柄冲,就是 mid 這個值,判斷 mid 是否等于等于 target储耐,然后來 break 或者是 return 這個 result,可以先把等于等于放在這里滨溉,只要它等于的話就馬上 return 即可什湘。

在這里的話我們假設是上升的就是升序排列的,如果 target 大于 array[mid] 的話說明什么晦攒?說明它在右側闽撤,那么要繼續(xù)向右查找,所以 left 就把左界向右進行移動變成 mid + 1 了脯颜,否則的話說明在這左側哟旗,那么右界的話就要向左移動變成 mid - 1 這么一個形式。

那么根據(jù)這里所謂的左下界和右下界為整形的情況下栋操,就是為 Integer 的情況下闸餐,在有些時候可能為實數(shù)的情況下,那么就沒有所謂的加一或減一矾芙,在這個地方就直接等于 mid 即可舍沙。另外在有些特殊的情況,這里直接是小于的這種情況下剔宪,后面在例題的時候會大家一個更深刻的了解拂铡。

示例

在遞增數(shù)組里
[10, 14, 19, 26, 27, 31, 33, 35, 42, 44]
查找:31

它中間有些數(shù)是不連續(xù)的,但總體是單調(diào)遞增的葱绒,我們要查31這么查感帅,如果是正常遍歷的話,就是查這個一次兩次三次四次五次六次查找地淀,它的mid值算出來就等于31失球。那么用 二分 的話這么辦呢?

二分的話首先我們要查的是31帮毁,算它的中間值她倘,中間值剛才等于27,31 和 27 對比大于27作箍,說明可以排除前半部分硬梁,繼續(xù)從后半部分進行查找,繼續(xù)查找胞得,只要查后半部分了荧止,前半部分白色就不用考慮了,繼續(xù)在灰色部分查找。

灰色部分的中間繼續(xù)算跃巡,mid 的話就等于 35危号,查 35 的話比 35 小就說明繼續(xù)在 27 的右側 35 的左側開始找,就在這個數(shù)組里面開始找素邪。它的 mid 值又算出來等于 33外莲,它小于 33 ,再繼續(xù)往左邊找兔朦,最后就找到了 31 這個數(shù)偷线。

所以它是油左右兩個邊界不斷地向中間進行夾逼的過程,這種夾逼的過程又由于這個數(shù)組本身它是單調(diào)遞增的沽甥,所以我們每次可以排除一半声邦,你可以認為有點像二叉搜索樹一樣的特性,但這里的是用數(shù)組來進行實現(xiàn)的摆舟,而二分查找本身這種有序性的話亥曹,很多時候在數(shù)學里面的話用得也特別多,恨诱。


部分圖片來源于網(wǎng)絡媳瞪,版權歸原作者,侵刪照宝。
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末材失,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子硫豆,更是在濱河造成了極大的恐慌龙巨,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件熊响,死亡現(xiàn)場離奇詭異旨别,居然都是意外死亡,警方通過查閱死者的電腦和手機汗茄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門秸弛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人洪碳,你說我怎么就攤上這事递览。” “怎么了瞳腌?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵绞铃,是天一觀的道長。 經(jīng)常有香客問我嫂侍,道長儿捧,這世上最難降的妖魔是什么荚坞? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘报强。我一直安慰自己,他們只是感情好诡挂,可當我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著临谱,像睡著了一般璃俗。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上吴裤,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天旧找,我揣著相機與錄音溺健,去河邊找鬼麦牺。 笑死,一個胖子當著我的面吹牛鞭缭,可吹牛的內(nèi)容都是我干的剖膳。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼岭辣,長吁一口氣:“原來是場噩夢啊……” “哼吱晒!你這毒婦竟也來了?” 一聲冷哼從身側響起沦童,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤仑濒,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后偷遗,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體墩瞳,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年氏豌,在試婚紗的時候發(fā)現(xiàn)自己被綠了喉酌。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡泵喘,死狀恐怖泪电,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情纪铺,我是刑警寧澤相速,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站鲜锚,受9級特大地震影響和蚪,放射性物質(zhì)發(fā)生泄漏止状。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一攒霹、第九天 我趴在偏房一處隱蔽的房頂上張望怯疤。 院中可真熱鬧,春花似錦催束、人聲如沸集峦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽塔淤。三九已至,卻和暖如春速妖,著一層夾襖步出監(jiān)牢的瞬間高蜂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工罕容, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留备恤,地道東北人。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓锦秒,卻偏偏與公主長得像露泊,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子旅择,可洞房花燭夜當晚...
    茶點故事閱讀 45,092評論 2 355