二分查找
1、问题描述
在一个有序(升序)数组查找一个数 x
2、算法分析
暴力的做法就是拿 x 跟数组里面每个数比较一下,然后返回找到的 x 的下标。这里明显可以使用分治的思想:可以把数组分成很多部分,在每个部分里面查找 x。如果所有部分都没有找到 x,那么把这些子问题合并起来后,表示整个数组里没有 x。
这很好的反应了分治的思想,先分解成很多小问题,解决这些小问题,把解决的小问题合并起来,大问题就解决了。
![BinarySearch.gif](https://upload-images.jianshu.io/upload_images/5294842-0304bad00d5daf55.gif?imageMogr2/auto-orient/strip)
3、代码实现
递归:
#include <stdio.h>
#include <string.h>
/**
* @param a 需要二分的升序数组
* @param x 需要查找的数字
* @param low 低位
* @param high 高位
*/
int binarysearch(int a[], int x, int low, int high)
{
if(low > high) {
return -1; // 没有找到
}
int mid = (low + high) >> 1;
if(x == a[mid]) {
return mid; // 找到 x
}
else if(x > a[mid]) {
return binarysearch(a, x, mid + 1, high); // 在后半部分继续二分查找
}
else {
return binarysearch(a, x, low, mid - 1); // 在前半部分继续二分查找
}
}
int main()
{
int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int idx = binarysearch(a, 2, 0, 9);
if(idx == -1) {
printf("未查到!\n");
}
else {
printf("查到了!数组下标 = %d\n", idx);
}
return 0;
}
非递归:
#include <stdio.h>
int BinarySearch(int a[], int n, int key)
{
if (n == 0) return -1;
int left = 0, mid, right = n - 1;
while (left <= right) {
mid = (left + right) >> 1;
if (a[mid] < key) {
left = mid + 1;
}
else if (a[mid] > key) {
right = mid - 1;
}
else {
return mid;
}
}
return -1;
}
int main()
{
int a[] = { 1, 3, 5, 8, 22, 45, 65, 78, 79, 102 };
printf("%d", BinarySearch(a, 10, 65));
return 0;
}