二分查詢的迴圈條件及指標終止位置問題

别来丶發表於2024-07-09

二分查詢的迴圈條件及指標終止位置問題

常見的二分搜尋法的迴圈迭代方法分為:左閉右開左閉右閉 兩種方式

  • 左閉右開:由於右邊界開放,例如[1,1)是矛盾的,因此迴圈條件為while(l<r)。閉合指後續迭代仍需要進行對其元素進行比較。因此每次迭代結束,左指標l移動到中點的下一位l = mid+1,而不需要移動到中點位置,因為中點位置已被和目標值比較過;開放意味著後續不需要再進行比較,因此每次右指標r需要移動到已經比較過的中點位置mid

  • 左閉右閉:由於右邊界閉合,例如[1,1]是合理的,因此迴圈條件為 while(l<=r);由於左右邊界都閉合,這意味著後續迭代需要對左右邊界即lr指向的元素進行判斷。因此每次迭代結束,左指標l移動到中點的下一位l = mid+1,右指標r移動到中點的前一個位置r = mid-1,因為mid位置已經被比較過了。

詳細解釋為什麼while(l<r)時需要右指標r移動到mid,而while(l<=r)時需要右指標r移動到mid-1:首先,這兩種情況下,每次迴圈的不變數都是左指標要移動到mid的下一位(左閉)。

  • while(l<r)時,我們考慮l+1=r這種情況,即l指標位於r指標的前一位,此時mid指向l:(1)若目標值target < nums[mid]=nums[l],此時r指標移動到mid也就是l的位置,l=r正常結束。(2)若目標值target > nums[mid]=nums[l]l指標移動到mid的下一位r的位置,此時l=r迴圈結束,但r指向的元素未被判斷。這就要求我們在先前已經對右指標r指向的元素進行過判斷,結束才是合理的。因此,因此當移動右指標時,我們必須保證右指標指向的元素是在先前已經被判斷過的,所以每次右指標要移動到mid的位置,若移動到mid-1,那麼r指標指向的位置就沒有被判斷,在上述情況下,就是錯誤的結束。同時這就是 右開 的由來,每次迴圈不用判斷r指向的元素,因為它在上次移動到的是已經比較過的元素的位置。

  • while(l<=r),同樣考慮l+1=r這種情況:(1)情況同上相同。(2)當目標值target > nums[mid]=nums[l]時,l指標移動到mid的下一位r的位置,l=r仍未結束,此時mid=l=r對r進行判斷。這意味著右指標r指向的元素在後續會被判斷到,這就要求,我們每次迭代改變右指標r的位置時,是先前未被判斷過的即可,即每次r指標移動到mid-1的位置。這是 右閉 的由來,因為右邊界r的指向未被比較過,需要在後續比較。

mid = ( l + r ) / 2下,指標終止情況

針對以上兩種迴圈迭代方法,本文列舉了所有指標終止位置的情況。其中包括不引入輔助元素、引入左邊界輔助元素、引入右邊界輔助元素以及同時引入左右邊界輔助元素時,左右指標的終止位置情況。旨在將規律具象化,便於理解。(注:在不越界的情況下,令 mid = ( l + r ) / 2)

不引入輔助元素

引入左邊界

引入左邊界

引入右邊界

引入右邊界

引入左右邊界

引入左右邊界

總結

左閉右開:

  • 在不引入輔助邊界的情況下,除了大於右邊界的目標值,左右指標lr共同指向第一個大於目標的數
  • 當引入了右輔助邊界時,左右指標lr共同指向第一個大於目標的數。

左閉右閉:

  • 無論是否引入左右輔助邊界,右指標r始終指向小於目標的最近位置的數,左指標l始終指向大於目標的最近位置的數


mid = ( l + r + 1) / 2下,指標終止情況

mid = ( l + r +1) / 2

相關文章