一、二分法查找思想
- 首先从数组的中间mid开始查找,如果刚好等于要查找的值,则返回这个数字的所在位置。
- 如果要查找的数字比mid值小,则让mid-1,做为数组的右边界,重复(1)操做;如果要查找的数字比mid大,则让mid+1做为数组的左边界,重复(1)操作。
- 如果left=right时,还没有找到该数字,则此数字不存在于这个数组当中。
如图:
二、二分法查找的前提条件
- 必须是顺序表
- 顺序表中的数字必须有序
三、代码实现
第一种:非递归实现 时间复杂度为O(log2^n)
#include<stdio.h>
int Searchval(int *arr,int n,int val)
{
int pos=-1;
if(arr==NULL||n<=0)
{
return pos;
}
int left=0;right=n-1;
while(right>=left)
{
int mid=(right-left)/2+left;防止溢出
if(arr[mid]>val)
{
right=mid-1;
}
else if(arr[mid]<val)
{
left=mid+1;
}
else
{
while(right>left&&val=arr[mid-1]) mid--;
break;
}
}
return pos;
}
int main()
{
int arr[]={0,0,1,2,2,3,4,5,6,7,8,9};
int n=sizeof(arr)/sizeof(arr[0]);
int pos=FindVal(arr,n,7);
printf("%d\n",pos);
return 0;
}
第二种:递归算法
#include<stdio.h>
int Search(int *arr,int left,int right,int val)
{
int pos=-1;
if(right>=left)
{
int mid=(right-left)/2+left;
if(val>arr[mid])
{
pos=Search(arr,mid+1,right,val);
}
else if(val<arr[mid])
{
pos=(arr,left,mid-1,val);
}
else
{
while(mid>left&&val=arr[mid-1]) --mid;
pos=mid;
}
}
return pos;
}
int SearchVal(int *arr,int n,int val)
{
int pos=-1;
if(arr==NULL||n<=0) return pos;
return SearchVal(arr,0,n-1,val);
}
int main()
{
int arr[]={0,0,1,2,2,3,4,5,6,7,8,9};
int n=sizeof(arr)/sizeof(arr[0]);
int pos=SearchVal(arr,n,2);
printf("%d\n",pos);
return 0;
}