参见编程珠玑chap4 chap9,和编程之美3.3
给定一个有序(不降序)数组arr,,
- 求任意一个i使得arr[i]等于t,不存在返回-1
不变式:x[low]< =t<=x[high]
int biSearch(int *arr, int low, int high, int t) { int mid; while(low<=high) { mid=low+(high-low)/2; if(arr[mid]==t) { return mid; } else if(arr[mid]>t) { high=mid-1; } else { low=mid+1; } } return -1; }
- 如存在重复元素,求最小的i使得arr[i]等于t,不存在返回-1
不变式:x[low]<
t<=x[high], return high
1 int biSearch(int *arr, int start, int end, int t) 2 3 { 4 5 int high, low, mid; 6 7 //x[l]<t=<x[u] 8 9 high=end+1; 10 11 low=start-1; 12 13 while(low+1!=high) 14 15 { 16 17 mid = low + (high-low)/2; 18 19 if(t<=arr[mid]) 20 21 { 22 23 high=mid; 24 25 } 26 27 else 28 29 { 30 31 low=mid; 32 33 } 34 35 } 36 37 if(high>=end+1 || arr[high]!=t) 38 39 { 40 41 return -1; 42 43 } 44 45 else 46 47 { 48 49 return high; 50 51 } 52 53 }
- 如存在重复元素,求最大的i使得arr[i]等于t,不存在返回-1
不变式:x[low]<= t<x[high], return low
1 int biSearch(int *arr, int start, int end, int t) 2 3 { 4 5 int high, low, mid; 6 7 //x[l]<=t<x[u] 8 9 high=end+1; 10 11 low=start-1; 12 13 while(low+1!=high) 14 15 { 16 17 mid = low + (high-low)/2; 18 19 if(t<arr[mid]) 20 21 { 22 23 high=mid; 24 25 } 26 27 else 28 29 { 30 31 low=mid; 32 33 } 34 35 } 36 37 if(low<=start-1 || arr[low]!=t) 38 39 { 40 41 return -1; 42 43 } 44 45 else 46 47 { 48 49 return low; 50 51 } 52 53 }
- 求最大的i使得arr[i]小于t,不存在返回-1;
不变式: x[low] <t<=x[high], return low
1 int biSearch(int *arr, int start, int end, int t) 2 3 { 4 5 int high, low, mid; 6 7 //x[l]<t=<x[u] 8 9 high=end+1; 10 11 low=start-1; 12 13 while(low+1!=high) 14 15 { 16 17 mid = low + (high-low)/2; 18 19 if(t<=arr[mid]) 20 21 { 22 23 high=mid; 24 25 } 26 27 else 28 29 { 30 31 low=mid; 32 33 } 34 35 } 36 37 if(low<=start-1 || arr[low]>t) 38 39 { 40 41 return -1; 42 43 } 44 45 else 46 47 { 48 49 return low; 50 51 } 52 53 }
- 求最小的i使得arr[i]大于t,不存在返回-1;
不变式:x[low]<=t<x[high],return high
略
测试程序:
1 #include <iostream> 2 3 using namespace std; 4 5 6 void init(int *a, int n) 7 { 8 for(int i=0; i<n; i++) 9 { 10 a[i]=(i)/3+1; 11 } 12 } 13 14 void print(int *a, int n) 15 { 16 for(int i=0; i<n; i++) 17 { 18 cout<<a[i]<<" "; 19 } 20 cout<<endl; 21 } 22 23 int biSearch(int *arr, int start, int end, int t) 24 { 25 int high, low, mid; 26 //x[l]<t=<x[u] 27 high=end+1; 28 low=start-1; 29 while(low+1!=high) 30 { 31 mid = low + (high-low)/2; 32 if(t<=arr[mid]) 33 { 34 high=mid; 35 } 36 else 37 { 38 low=mid; 39 } 40 } 41 if(low<=start-1 || arr[low]>t) 42 { 43 return -1; 44 } 45 else 46 { 47 return low; 48 } 49 } 50 51 int main() 52 { 53 int n=5; 54 int arr[n]; 55 56 init(arr, n); 57 print(arr, n); 58 for(int i=-2; i<n+1; i++) 59 cout<<i<<":"<<biSearch(arr, 0, n-1, i)<<endl; 60 61 62 return 0; 63 }