/*
p is the start index,
q is the end index,
x is the target data
*/
int binary_search(int x, int p, int q, int *a) {
if (p >= q && a[p] != x)
return -1;
int m = (p + q) / 2;
if (a[m] == x)
return m;
if (x > a[m])
p = m + 1;
else
q = m - 1;
return binary_search(x, p, q, a);
}
#include <stdio.h>
#define N 20
int arr[N] = {9,10,11,12,13,14,15,16,17,18,19,0,1,2,3,4,5,6,7,8};
void print_header(int target) {
printf("search :%2d %*c | ", target, 5, ' ');
for (int i = 0; i < N; i++) {
printf("%2d ", i);
}
printf("\n");
for (int i = 0; i< N; i++) {
printf("-----");
}
printf("\n");
}
void print_array(int p, int m, int q, int *a) {
printf("p=%2d, m=%2d, q=%2d |%*c", p, m, q, 4 * p + (p>0?1:0), ' ');
for (int i = p; i <= q; i++) {
printf("%2d, ", a[i]);
}
printf("\n");
}
/* 非递归方式 */
int search_loop_array(int x, int* a, int length) {
int p = 0;
int q = length - 1;
while ( p <= q ) {
int m = ( p + q ) / 2;
print_array(p, m, q, a);
if ( x == a[m] )
return m;
if ( x > a[m] ) {
int mm = ( m + q ) / 2;
int increase = (a[m] <= a[mm] && a[mm] <= a[q]);
if ( ( increase && x <= a[q] ) || ! increase)
p = m + 1;
else
q = m - 1;
} else {
int mm = ( p + m ) / 2;
int increase = a[p] <= a[mm] && a[mm] <= a[m];
if ( increase && x >= a[p] || !increase)
q = m - 1;
else
p = m + 1;
}
}
return -1;
}
/* 递归方式 */
int search_loop_array2(int x, int low, int high, int* a) {
if (low >= high && a[low] != x)
return -1;
int m = (low + high) / 2;
print_array(low, m, high, a);
if ( x == a[m] )
return m;
if ( x > a[m] ) {
int mm = (m + high) / 2;
int increase = (a[m] <= a[mm] && a[mm] <= a[high]);
if ( !increase || (increase && x <= a[high] ) )
low = m + 1;
else
high = m - 1;
} else {
int mm = (low + m) / 2;
int increase = (a[low] <= a[mm] && a[mm] <= a[m]);
if ( !increase || (increase && x >= a[low] ) )
high = m - 1;
else
low = m + 1;
}
return search_loop_array2(x, low, high, a);
}
int main() {
for (int i = 0; i < N; i++) {
print_header(i);
// printf("result: %d\n\n", search_loop_array(i, arr, N));
printf("result: %d\n\n", search_loop_array2(i, 0, N-1, arr));
}
return 0;
}