二分查詢各種情況大總結

2021-08-18 22:11:37 字數 2752 閱讀 5456

本文**:

二分查詢多次刷題時遇到,雖然每次也能寫對,但花了蠻多時間,沒好好想過。而且網上的太多版本,並不是很簡潔,而且邊界條件變化情況太多,容易混淆,下面是自己對二分查詢的一些思考和總結,盡量寫得簡單易懂。

三種基本版本:

1.1 二分查詢原始版–查詢某個數的下標(任意乙個)

在有序陣列中查詢某個數,找到返回數的下標,存在多個返回任意乙個即可,沒有返回-1。所有程式採用左右均為閉區間,即函式中n為最後乙個元素下標,而不是元素個數。典型**如下:

public

intbinarysearch(int a, int n, int key) else

if(key < a[mid]) else

} return -1;

}

1.2 查詢第乙個大於等於某個數的下標

例:int a = ,查詢2,返回第乙個2的下標1;查詢3,返回4的下標4;查詢4,返回4的下標4。如果沒有大於等於key的元素,返回-1。

下面是**,改動只有兩處:

public

intfirstgreatorequal(int a, int n, int key) else

} return low <= n ? low : -1;

}

解釋:

1、條件為key<=a[mid],意思是key小於等於中間值,則往左半區域查詢。如在 查詢2,第一步,low=0, high=6, 得mid=3, key <= a[3],往下標中繼續查詢。

2、終止前一步為: low=high,得mid = low,此時如果key <= a[mid],則high會改變,而low指向當前元素,即為滿足要求的元素。如果key > a[mid],則low會改變,而low指向mid下乙個元素。

3、如果key大於陣列最後乙個元素,low最後變為n+1,即沒有元素大於key,需要返回 -1。

1.3 查詢第乙個大於某個數的下標

例:int a = ,查詢2,返回4的下標4;查詢3,返回4的下標4;查詢4,返回8的下標5。如果沒有大於key的元素,返回-1。

如下是**,與上面大於等於某個數僅判斷乙個符號不同:

public

intfirstgreat(int a, int n, int key) else

} return low <= n ? low : -1;

}

以上原型的擴充套件應用

2.1 查詢陣列中某個數的位置的最小下標,沒有返回-1

直接用上面1.2,但需要處理一下,即當返回的low位置不等於key時,也返回-1。如下:

public

intfirstindex(int a, int n, int key) else

} return (low <= n) && (a[low] == key) ? low : -1;

}

2.2 查詢陣列中某個數的位置的最大下標,沒有返回-1

直接用上面1.3,得到的下標 - 1即可,但也需要處理一下,即不用判斷low <= n,而是判斷low-1>=0,且返回的low-1位置等於key時,才返回位置low - 1。如下:

public

intlastindex(int a, int n, int key) else

} return (low - 1 >= 0 && (a[low - 1] == key))? low - 1: -1;

}

2.3 查詢陣列中小於某個數的最大下標,沒有返回-1

直接用上面1.2,返回的low-1位置即為可能的位置。也需要處理一下,需要low-1>=0。

public

intfirstless(int a, int n, int key) else

} return (low - 1 >= 0) ? low - 1 : -1;

}

2.4 查詢陣列中某個數的出現次數

直接使用1.2,1.3即可,但需要修改1.2,1.3的返回條件,當low>n時,直接返回low。舉例說明:int a = ,查詢10的個數,根據1.2程式得到low = 6,而1.3程式返回值 = -1,不符合。因此需要將1.3得到的low = n + 1值返回即可。同理,如果查詢15,此時1.2程式返回值為-1,也得改為直接返回low = n+1。

使用1.2,1.3,分別求得下界first和上界last,兩個相減即(last - first)是key出現次數。如下:

public

intgetcount(int a, int n, int key)

public

intfirstgreatorequal2(int a, int n, int key) else

} return low;

} public

intfirstgreat2(int a, int n, int key) else

} return low;

}

總結下:

1、寫此文章的目的是總結多種二分查詢相似問題,網上的太多**,邊界條件雜亂且不容易理解。這裡先總結出最基本的三種情況**,再用三種情況的**求解相似問題,理解複雜度降低。

2、一些問題,需要自己多總結,才能有理解深刻,才能寫出最適合自己理解的**。

本文**已測試過,如有錯誤,請不吝賜教。

死鎖的各種情況總結

mutex 代表乙個全域性互斥物件 voida mutex.unlock return 複製 由於在if的執行體內直接retun,而沒有呼叫unlock,導致另乙個執行緒再呼叫a方法就出現死鎖。void sub func void data process 複製 void data process1...

apns 推送的各種情況總結

iphone應用程式 1 從給定的類名初始化應用 2 從給定的應用程式委託類,初始化乙個應用程式委託。並把該委託設定為應用程式的委託,這裡就有如果傳入引數為nil,會呼叫函式訪問 info.plist檔案來尋找主nib檔案,獲取應用程式委託。3 啟動主事件迴圈,並開始接收事件。1 負責處理到來的使用...

二分查詢總結

今天上csdn,發現一篇關於二分查詢演算法的文章被置頂,回帖也相當熱烈。我覺得演算法總重要的還是要了解思想,至於程式設計技巧則是其次。二分查詢在計算中演算法中的重要性不言而喻,許多變形的演算法都是基於此演變的,比如二分查詢樹等。所以此演算法程式我也打算總結一下。當然經典的演算法討論莫過於jon be...