二分搜索算法常見使用誤區


  • 直接使用二分搜索法,搜索一個無序的數組或集合。算法

    若是你運氣好的話,可能會搜索到你想要的數據,可是大部分狀況下你不能獲得你想要的結果。由於二分搜索是按照中間值來計算你要搜索數據的範圍,每次逐漸縮小範圍。若是你的結果不在一個按照升序排列的數組中,你要搜索的數據極可能被遺棄,而後返回負值。咱們能夠經過以下所示一段程序來斷言,數組是不是有序的。數組

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;

若是一個有序數組中,存在相同的數字,咱們怎麼保證返回全部的呢?

相關文章
相關標籤/搜索