演算法訓練之二分查詢小結(C )

2021-10-05 05:44:30 字數 1642 閱讀 2944

從這週的習題和每日一題來看,二分查詢雖然思想簡單,但變體眾多,且極易出錯。因此,小結以求避坑。

參考:王爭老師的專欄 二分查詢(上)

二分查詢(下)

先給出二分查詢模板(c++):

int low = 0;

int high = n - 1;

while (low <= high) else if (a[mid] < value) else

}

其中,關鍵有三點:

迴圈退出條件是 low <= high,而不是 low < high

mid取值,用位運算形式加速,即模板中所示

low 和 high 的更新

至於變體形式,目前所遇到的情況,基本是在如何更新low和high,及在更新的同時完成目標任務上下功夫。這些題目應該是可以直接套用二分查詢模板的,當然這樣可能會囉嗦些,不過也是很好的訓練機會。

再者,什麼時候可以用二分查詢呢?

大抵以下幾點要求:

依靠順序表結構實現,且最好是陣列(鍊錶的話效率太低)

針對的一定是有序資料(起碼得是半有序吧)

更適合處理靜態資料,無頻繁插入刪除為佳

最後,給出四個常用變體形式:

//變體一:查詢第乙個值等於給定值的元素

public int bsearch(int a, int n, int value) else if (a[mid] < value) else

} return -1;

}//變體二:查詢最後乙個值等於給定值的元素

public int bsearch(int a, int n, int value) else if (a[mid] < value) else

} return -1;

}//變體三:查詢第乙個大於等於給定值的元素

public int bsearch(int a, int n, int value) else

} return -1;

}//變體四:查詢最後乙個小於等於給定值的元素

public int bsearch7(int a, int n, int value) else

} return -1;

}

附乙個思考題:使用二分查詢,尋找乙個半有序陣列 [4, 5, 6, 7, 0, 1, 2] 中間無序的地方

//假定為公升序排列且無重複元素,這個問題其實和leetcode 153題(尋找旋轉排序陣列中的最小值)類似

//找出最小元素所在下標,若下標不為0(即非有序陣列),則該下標往後直至陣列末尾都是無序

class solution

low = mid + 1;

}else if (nums[mid] < nums[low])

high = mid - 1;

}else

if (min_num < nums[high])

break;}}

return min_index;

}};

演算法之二分查詢

總時間限制 1000ms 記憶體限制 65536kb 描述在乙個非降序列中,查詢與給定值最接近的元素。輸入第一行包含乙個整數n,為非降序列長度。1 n 100000。第二行包含n個整數,為非降序列各元素。所有元素的大小均在0 1,000,000,000之間。第三行包含乙個整數m,為要詢問的給定值個數...

演算法之二分查詢

二分查詢演算法是運用分治策略的典型例子。給定一組已經排好序的n個元素a n 從這n個元素中找到乙個特定元素x。基本思想 將n 個元素劃分成個數大致相同的兩部分,取中間元素a n 2 與x進行比較 如果x a n 2 即找到x,演算法終止 如果x如果x a n 2 則只在陣列a的右半部分繼續查詢x。c...

演算法之二分查詢

二分查詢針對的是乙個有序的資料集合,查詢思想有點類似分治思想,每次都通過跟區間的中間元素對比,將待查詢的區間縮小為之前的一半,直到找到想要查詢的元素,或是區間被縮小為0。二分查詢的時間複雜度為o l ogn o logn o logn l og nlogn logn 是乙個非常恐怖的數量級,即使n非...