直接使用二分搜索法,搜索一個無序的數組或集合。算法
若是你運氣好的話,可能會搜索到你想要的數據,可是大部分狀況下你不能獲得你想要的結果。由於二分搜索是按照中間值來計算你要搜索數據的範圍,每次逐漸縮小範圍。若是你的結果不在一個按照升序排列的數組中,你要搜索的數據極可能被遺棄,而後返回負值。咱們能夠經過以下所示一段程序來斷言,數組是不是有序的。數組
for(int i=0; i< arr.length; i++) { if(arr[i]>arr[i+1]) { return 0 } return 1; }
由於你的邊界沒有徹底控制好,因此形成了這種狀況。以下:調試
反面教材 1: 數組 int arr[] = {12,14,143,145,643,23453,233452};
搜索數據 233452(直接陷入死循環)code
int start = 0; int end = arr.length-1; while(start <= end) { int mid = (start + end) / 2; if(key < arr[mid]){ end = mid; }else if(key > arr[mid]) { start = mid; }else { return mid; } } return -1;
如上這種寫法看起貌似是正確的,若是仔細分析的話,會發現數組的長度爲7搜索
第一次循環中間量mid=3循環
第二次循環中間量mid=4程序
第三次循環中間量mid=5數據
第四次循環中間量mid=6集合
第五次循環中間量mid=6while
第六次循環中間量mid=6
第七次循環中間量mid=6
.....
由此陷入死循環
反面教材 2: 若是咱們經過調試以後,把程序調整成以下,循環搜索結果,發現依然是個死循環。最終卡在了中間值5上,究其緣由是由於,咱們的中間值不能一直縮小,因此最終致使這個問題。
int start = 0; int end = arr.length-1; while(start <= end) { int mid = (start + end) / 2; if(key < arr[mid]){ end = mid + 1; }else if(key > arr[mid]) { start = mid - 1; }else { return mid; } } return -1;
正確寫法以下:(迭代過程當中,循環不斷減少。)
int start = 0; int end = arr.length-1; while(start <= end) { int mid = (start + end) / 2; if(key < arr[mid]){ end = mid - 1; }else if(key > arr[mid]) { start = mid + 1; }else { return mid; } } return -1;
若是一個有序數組中,存在相同的數字,咱們怎麼保證返回全部的呢?