在上题基础上,如果元素可以重复的话,那么就需要修改getPos,因为有可能直接得到的最小值不是正好在分界的地方。修改在第34行。
1 int findPos(int A[], int left, int right){ 2 if(left > right) 3 return -1; 4 int mid = (left+right)/2; 5 int result; 6 if(A[left] > A[mid]){ 7 result = findPos(A, left, mid-1); 8 if(result == -1) 9 return mid; 10 else 11 return A[result]<A[mid]?result:mid; 12 } 13 else{ 14 result = findPos(A, mid+1, right); 15 if(result == -1) 16 return left; 17 else 18 return A[left]<A[result]?left:result; 19 } 20 } 21 int bsearch(int A[], int left, int right, int target){ 22 if(left > right) 23 return -1; 24 int mid = (left+right)/2; 25 if(A[mid] == target) 26 return mid; 27 else if(A[mid] < target) 28 return bsearch(A, mid+1, right, target); 29 else 30 return bsearch(A, left, mid-1, target); 31 } 32 bool search(int A[], int n, int target) { 33 int pos = findPos(A, 0, n-1); 34 while(pos > 0 && A[pos] == A[pos-1]) 35 pos--; 36 int result = bsearch(A, 0, pos-1, target); 37 if(result == -1) 38 result = bsearch(A, pos, n-1, target); 39 if(result == -1) 40 return false; 41 return true; 42 }
思路二的修改是如果A[m] == A[l]时,要两边都进行判断
1 bool search2(int A[], int n, int target, int l, int r){ 2 if(n == 0) 3 return false; 4 int m; 5 while(l <= r){ 6 m = (l+r)/2; 7 if(A[m] == target) 8 return true; 9 else if(A[m] > A[l]){ 10 if(target < A[m] && target >= A[l]) 11 r = m-1; 12 else 13 l = m+1; 14 } 15 else if(A[m] < A[l]){ 16 if(target > A[m] && target <= A[r]) 17 l = m+1; 18 else 19 r = m-1; 20 } 21 else 22 return search2(A, n, target, l, m-1) || search2(A, n, target, m+1, r); 23 } 24 return false; 25 } 26 bool search(int A[], int n, int target) { 27 return search2(A, n, target, 0, n-1); 28 }