給定乙個有序的陣列,查詢某個數是否在陣列中,請程式設計實現。
一看到陣列本身已經有序,我想你可能反應出了要用二分查詢,畢竟二分查詢的適用條件就是有序的。那什麼是二分查詢呢?
二分查詢可以解決(預排序陣列的查詢)問題:只要陣列中包含t(即要查詢的值),那麼通過不斷縮小包含t的範圍,最終就可以找到它。其演算法流程如下:
對於包含n個元素的表,整個查詢過程大約要經過log(2)n次比較。
此時,可能有不少讀者心裡嘀咕,不就二分查詢麼,太簡單了。
然《程式設計珠璣》的作者jon bentley曾在貝爾實驗室做過乙個實驗,即給一些專業的程式設計師幾個小時的時間,用任何一種語言編寫二分查詢程式(寫出高階偽**也可以),結果參與編寫的一百多人中:90%的程式設計師寫的程式中有bug(我並不認為沒有bug的**就正確)。
也就是說:在足夠的時間內,只有大約10%的專業程式設計師可以把這個小程式寫對。但寫不對這個小程式的還不止這些人:而且高德納在《計算機程式設計的藝術 第3卷 排序和查詢》第6.2.1節的「歷史與參考文獻」部分指出,雖然早在2023年就有人將二分查詢的方法公諸於世,但直到2023年才有人寫出沒有bug的二分查詢程式。
當然,能正確寫出來不代表任何什麼,不能正確寫出來亦不代表什麼。
//二分查詢v0.1實現版//首先要把握下面幾個要點:
//right = n-1 => while(left <= right) => right = middle-1;
//right = n => while(left < right) => right = middle;
//middle的計算不能寫在while迴圈外,否則無法得到更新。
int binarysearch(int array, int n, int value)
else if(array[middle] < value)
else
return middle;
//可能會有讀者認為剛開始時就要判斷相等,但畢竟陣列中不相等的情況更多
//如果每次迴圈都判斷一下是否相等,將耗費時間
}return -1;
}
編寫正確的二分查詢程式,首先要把握下面幾個要點:
right = n-1 => while(left <= right) => right = middle-1;
middle的計算不能寫在while迴圈外,否則無法得到更新。
還有乙個最最常犯的錯誤,具體可以參考 extra, extra - read all about it: nearly all binary searches and mergesorts are broken ,其中提到了jdk5中該bug:
middle = (left+right)>>1; 這樣的話left與right的值比較大的時候,其和可能溢位。
這個也是錯誤的:
right = n => while(left < right) => right = middle;
如果搜尋陣列中不存在的數字的時候,可能會導致死迴圈,因為最後left = middle, right = middle + 1,這樣每次更新left和middle總是不變的。
二分查詢時:left <= right,right = middle - 1;left < right,right = middle;
//演算法所操作的區間,是左閉右開區間,還是左閉右閉區間,這個區間,需要在迴圈初始化,//迴圈體是否終止的判斷中,以及每次修改left,right區間值這三個地方保持一致,否則就可能出錯.
//二分查詢實現一
int binarysearch(int array, int n, int v)
else if (array[middle] < v)
else
}return -1;
}//二分查詢實現二
int binarysearch(int array, int n, int v)
else if (array[middle] < v)
else
}return -1;
}
二分查詢法
二分查詢要求 1.必須採用順序儲存結構 2.必須按關鍵字大小有序排列。優缺點 折半查詢法的優點是比較次數少,查詢速度快,平均效能好 其缺點是要求待查表為有序表,且插入刪除困難。因此,折半查詢方法適用於不經常變動而查詢頻繁的有序列表。演算法思想 首先,將表中間位置記錄的關鍵字與查詢關鍵字比較,如果兩者...
二分查詢法
有序陣列中的find 方法 public int find long serchkey int lowerbound 0 int upperbound nelems 1 while true curin lowerbound upperbound 2 if a curin serchkey retu...
二分查詢法
演算法基本思想 二分查詢演算法的前置條件是,乙個已經排序好的序列 假設這個序列是公升序排列的 這樣在查詢所要查詢的元素時,首先與序列中間的元素進行比較,如果大於這個元素,就在當前序列的後半部分繼續查詢,如果小於這個元素,就在當前序列的前半部分繼續查詢,直到找到相同的元素,或者所查詢的序列範圍為空為止...