如何寫好乙個二分搜尋

2021-10-09 20:39:39 字數 3003 閱讀 3435

最近寫了乙個二分搜尋,結果不盡人意,總是出錯。

所以翻了一些部落格,看到一些關於使用迴圈不變體的方法來寫二分搜尋。

如何寫出正確的二分搜尋--

我就寫好乙個二分搜尋進行了一下總結:

確定你這個二分的目的,以下會舉7個例子說一下常用的求解target;

確定條件,就三個,s[mid]>、==、確定迴圈的條件 while(left<=right),while(left

以下就手動舉例編碼對以上步驟進行實現。

/**

* target:搜尋確定的key值

** 1. left<=right ----- 保證退出迴圈的時候,陣列沒數(left>right)裡面的數為0,沒找到就返回-1

* 2. left=mid+1 ----- s[mid]key 只可能在 [left,mid-1] 中

* 4. return mid ------ 找到就返回mid,找不到就返回-1

* 5. 每次縮小的範圍是right-mid+1 = ((right-left)>>1) +1 ,至少縮小乙個

* @param s

* @param key

* @return

*/public static int bs(int s,int key)

else if(s[mid]right)裡面的數為0,還沒找到就返回-1

* || 或者裡面的還有1個數(left=right),判斷這個是否為key,返回left或者-1**

* 2. left=mid+1 ----- s[mid]key 只可能在 [left,mid-1] 中

** 4. right = mid ------ s[mid]=key 可能在 [left,mid] 中,(有一種寫法或者判斷s[mid-1]是不是key,不是就直接返回mid,是就right=mid-1)

** 5. 每次縮小的範圍是right-mid+1 = ((right-left)>>1) +1 ,至少縮小乙個。

* || 或者是 right-mid =(right-left)>>1 可能不會縮小,如果判斷條件是 right=left 或者 right=left+1 都不會縮小,會進入死迴圈。

* && 但是在 while(leftkey 和 s[mid]=key 的條件執行的結果合併為right= mid,因為 left>1);

if(s[mid]right)裡面的數為0,還沒找到就返回-1

* ||或者裡面的還有1個數(left=right),判斷這個是否為key,返回left或者-1

* ||或者裡面的還有2個數(left+1=right),判斷這個left和right是否為key,返回left或者right或者-1

** 2. left=mid+1 ----- s[mid]key 只可能在 [left,mid-1] 中

** 4. left = mid ------ s[mid]=key 可能在 [mid,right] 中,(思路:或者判斷s[mid+1]是不是key,不是就直接返回mid,是就令left=mid+1;)

** 5. 每次縮小的範圍是right-mid+1 = ((right-left)>>1) +1 ,至少縮小乙個。

* ||或者是 mid-left =(right-left)>>1 可能不會縮小,如果判斷條件是 right=left 或者 right=left+1 都不會縮小,會進入死迴圈。

* && 但是此時為什麼在 while(leftkey 和 s[mid]=key 的條件執行的結果合併為right= mid,因為 left>1);

if(s[mid]>key)

else

}if(s[right]==key)

if(s[left]==key)

return -1;

}

/**

* target:搜尋最近大於key的值

** 1. leftright)裡面的數為0,還沒找到就返回-1

* ||或者裡面的還有1個數(left=right),判斷這個是否為key,返回left或者-1

* ||或者裡面的還有2個數(left+1=right),判斷這個left和right是否為key,返回left或者right或者-1

** 2. left=mid+1 ----- s[mid]key 只可能在 [left,mid] 中(mid有可能是最近大於key的下標)(思路:或者判斷s[mid-1]是不是大於key,不是就直接返回mid,是就令right=mid-1;)

** 4. left = mid+1 ------ s[mid]=key 可能在 [mid+1,right] 中

** 5. 每次縮小的範圍是right-mid+1 = ((right-left)>>1) +1 ,至少縮小乙個。

* ||或者是 right-mid =(right-left)>>1 可能不會縮小,如果判斷條件是 right=left 或者 right=left+1 都不會縮小,會進入死迴圈。

* && 但是此時為什麼在 while(leftkey 得到right=mid,那麼需要再一次迴圈判斷,不滿足 left>1);

if(s[mid]>key)

else

}if(s[left]>key)

return -1;

}

/**

* target:搜尋最近小於key的值

* 經過以上4個例子理解,mid=left+((right-left)>>1)的特殊性,就可以直接寫出下面**。

* @param s

* @param key

* @return

*/public static int bsfirstlessthan(int s,int key)

else

}if(s[right]想要快速的寫出二分搜尋

明確三個條件;

mid=left+((right-left)>>1)的特殊性;

掌握基本的編寫結構,快速上手;

如何寫好乙個BUG報告?

為什麼是好的bug報告?如果您的錯誤報告是有效的,那麼它得到修復的機會就會更高。因此,修復bug取決於您如何有效地報告它。報告錯誤只是一種技能,我將解釋如何實現這一技能。編寫問題報告 bug報告 的目的是修復bug 由cemkaner編寫。如果測試人員沒有正確報告錯誤,程式設計師很可能會拒絕此錯誤,...

如何寫好乙個基礎的BaseActivity

public abstract class baseactivity extends activity 初始化載入布局 public abstract int initlayout 初始化布局view public abstract void initview 初始化資料及呼叫方法 public a...

軟體測試 測試用例 如何寫好乙個用例

測試用例 test case 是為某個測試目標而編制的一組測試輸入 執行步驟以及預期結果的集合,以便測試某 個程式的路徑或驗證軟體是否滿足某個特定需求,那麼怎麼寫好乙個用例呢?測試用例 test case 是為某個測試目標而編制的一組測試輸入 執行步驟以及預期結果的集合,以便測試某 個程式的路徑或驗...