二分查找有个前提,是待查找的序列或数组必须是一个有序的的序列或数组,否则二分查找算法就毫无意义,或者说根本就没法查了。
(如果别人给你一个无序的数组,就让你用二分查找算法实现一下查找,千万别上来抄起笔傻兮兮的写代码,这是一面试过程的陷进,
你的先用你学过的排序算法,对别人给你的无序数组从小到大排个序,在用二分查找去找)
二分查找的思想:在一个有序的数组或序列中先找出数组的中间元素和待查找元素去比较,如果二者相等,就返回此时的中间元素下标,否则就有两种情况
①中间元素比待查找元素小,那么我们就可以扔掉中间元素及其左侧所有元素(因为他们比中间元素还小,肯定比待查找元素要小了),
从剩下的右侧元素中找出中间元素比较去找
②中间元素比待查找元素大,那么我们就可以扔掉中间元素及其右侧所有元素(因为他们比中间元素还大,肯定比待查找元素要大了),
再从剩下的左侧元素中找出中间元素比较去找
此处给出二分查找就是通过循环实现的:
另外二分查找也可以通过递归实现(需要说明的是该算法递归实现的出口是中间元素和待查找元素相等,
另外如果待查找的数组的最小下标比最大下标还大,表明我们已经都找到最后一个子序列的最后一个元素还没找到),
#include <stdio.h>
int BinarySearch(int a[], int x, int arr_len){
int low = 0;
int high = arr_len - 1;
int mid;
while(low<=high)
{
mid = (low+high)/2;
if(a[mid]==x)
{
return mid;/*找到查找元素*/
}
else if(a[mid]<x)
{
low = mid+1;
}
else if(a[mid]>x)
{
high = mid-1;
}
}
return -1;
}
void PrintArray(int a[], int arr_len)
{
int i;
for(i=0;i<arr_len;i++)
{
printf("%d ", a[i]);
}
printf("\n");
}
int main()
{
int a[] = {2,4,6,8,10,11,12};
int arr_len = sizeof(a)/sizeof(int);
int i;
int b;
printf("从如下的数组中查找元素:");
PrintArray(a, arr_len);
printf("请输入一个待查找的元素:");
scanf("%d", &b);
i = BinarySearch(a, b, arr_len);
if(i!=-1)
{
printf("数组中元素的位置从0开始标记\n");
printf("待查找元素%d的位置是:%d", b, i);
}
else
{
printf("待查找元素%d没找到", b);
}
return 0;
}