二分查找算法思想非常簡單,就是折半查找一個有序序列,在這裡,我用二分查找一個順序排列的整形數組。若用C實現的話我們需要注意以下幾個方面:
1.如何判斷查找完成,定義返回值含義,定義退出循環條件
2.如何處理邊界問題,例如1 2 3 這個序列,當我們要查找1或者3時,會不會使程序出現BUG
3.對於數列來說,我們通常用整形存儲其下標,二分查找若取下標中間數,則會出現什麼樣的問題?這些問題是否會影響我們的查找,若有問題,則應該如何規避?
通常情況,作為一個初學者,我甚至覺得二分查找過於簡單,不值一提,最近經過思考,二分查找算法對於理論的要求並不是很高,但是若要把它變為有可行性的程序代碼,則我們需要思考諸多的細節,否則這個代碼寫出來則是錯誤百出的。
如何解決第一個問題,因為我們了解的二分查找的思路其實就是折半查找,要有左邊界與右邊界我們才能確定中間元素,當左邊界與右邊界重合的時候,這時查找對象就變為一個元素的,若它也不是索要查找的對象,那麼在所查找的集合中便沒有所需的元素。這樣我們就清楚地定義出來了所需參數,以及退出查找的條件。我們需要一個左邊界以及右邊界,還有中間元素,若右邊界比左邊界小(左比右大)時,退出循環,返回異常。若否,則執行 查找語句。
這裡的查找語句如何設計呢,若不結合第2,3個問題,我們可以隨手寫出代碼:
while(left<=right)
{
mid=(left+right)/2;
if(x>mid)
left=mid;
else if(x<mid)
right=mid;
else
return mid;
}
return error;
顯然這樣做的話實在是太理想了,按出數學的思路,這樣做是根本取不到邊界的,如果考慮到C語言中的整形會自動捨棄小數,那麼對於左邊界是我們這樣寫是完全可以的,但是右邊界是永遠都不會取到的,如果取中間值取到非整數,是否會在其他方面影響到我們的查找結果呢,答案是不會的,若產生自動捨棄小數的狀況,僅僅只會影響我們在一個有序序列中查找元素的位置與分段查找所分段的長度,並不會影響我們的查找結果,如果要解決邊界問題,我們可以使分段所產生的邊界偏移,由於mid元素已經被判斷過了,所以我們分段的時候段的邊界可以直接捨棄掉mid元素,使得邊界為mid+1或mid-1,這樣我們便完成了整型數組的二分查找,實現代碼如下:
#include <stdio.h>//二分查找算法即測試用例
int BinySerch(int *arr, int x, int lengh)//設計參數,由於是整形數組,所以我們必須傳遞他
{ //長度否則數組傳參時會發生降級
int left = 0, right = lengh - 1;
int mid ;
while (left <= right)
{
mid = left + (right - left) / 2;
if (x < arr[mid])
{
right = mid - 1;
}
else if (x > arr[mid])
{
left = mid + 1;
}
else
{
return mid;
}
}
return -1;
}
int main()//測試用例
{
int x = 0;
int arr[11] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int lengh = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < 12; i++)
{
printf("%d ",BinySerch(arr, i, lengh));
}
system("pause");
return 0;
}
若有不足之處,希望批評指正