通过 while 循环的方式,简单实现 C 语言的二分查找。
#include <stdio.h>
int binarySearch(int a[], int count, int key)
{
int low = 0;
int high = count-1;
while (low <= high) {
int mid = (low + high) / 2;
printf("low is %d, high is %d, mid is %d, a[mid] is %d, key is %d \n", low, high, mid, a[mid], key);
if (a[mid] == key) {
printf("- match -\n");
return mid;
} else if (a[mid] > key) {
printf("<- try\n");
high = mid - 1;
} else {
printf("try ->\n");
low = mid + 1;
}
}
return -1;
}
int main() {
int array[] = {1, 2, 3, 4, 5, 6, 7, 8};
printf("Input the key you want to search: \n");
int key;
scanf("%d", &key);
int location = binarySearch(array, 8, key);
if (location >= 0) {
printf("Find successed. location is %d and find key is %d\n", location, array[location]);
} else {
printf("Find failed.\n");
}
return 0;
}
运行验证如下:
- key 在左侧
➜ C ./a.out
Input the key you want to search:
1
low is 0, high is 7, mid is 3, a[mid] is 4, key is 1
<- try
low is 0, high is 2, mid is 1, a[mid] is 2, key is 1
<- try
low is 0, high is 0, mid is 0, a[mid] is 1, key is 1
- match -
Find successed. location is 0 and find key is 1
- key 超出左侧
➜ C ./a.out
Input the key you want to search:
0
low is 0, high is 7, mid is 3, a[mid] is 4, key is 0
<- try
low is 0, high is 2, mid is 1, a[mid] is 2, key is 0
<- try
low is 0, high is 0, mid is 0, a[mid] is 1, key is 0
<- try
Find failed.
- key 在右侧
➜ C ./a.out
Input the key you want to search:
8
low is 0, high is 7, mid is 3, a[mid] is 4, key is 8
try ->
low is 4, high is 7, mid is 5, a[mid] is 6, key is 8
try ->
low is 6, high is 7, mid is 6, a[mid] is 7, key is 8
try ->
low is 7, high is 7, mid is 7, a[mid] is 8, key is 8
- match -
Find successed. location is 7 and find key is 8
- key 超出右侧
➜ C ./a.out
Input the key you want to search:
9
low is 0, high is 7, mid is 3, a[mid] is 4, key is 9
try ->
low is 4, high is 7, mid is 5, a[mid] is 6, key is 9
try ->
low is 6, high is 7, mid is 6, a[mid] is 7, key is 9
try ->
low is 7, high is 7, mid is 7, a[mid] is 8, key is 9
try ->
Find failed.
总结
主要需要考虑 mid 在 while 循环中的修改,对于边界的情形,需要谨慎处理。
我在写的过程中,主要在以下三处出现过问题:
- 这里需要注意,low 与 high 遇到的时候,就是数组结束的时候。
while (low <= high) {...}
- 当找到的值比 key 大,这时候 key 在数组左侧,所以把 high 调整为 mid 的左侧一个,因为 mid 已经校验过,所以需要减一。
high = mid - 1;
- 当找到的值比 key 小,这时候 key 在数组右侧,所以把 low 调整为 mid 的右侧一个,因为 mid 已经校验过,所以需要加一。
low = mid + 1;