二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。
使用二分查找的条件:
1.必须采用顺序存储结构。
2.必须按关键字大小有序排列。
通俗一点的说:如果数据是一个数组,那么这个数组必须是有序的
思路:二分查找的基本思想是将n个元素分成大致相等的两部分,取a[n/2]与x做比较,如果x=a[n/2],则找到x,算法中止;如果x<a[n/2],则只要在数组a的左半部分继续搜索x,如果x>a[n/2],则只要在数组a的右半部搜索x.
时间复杂度:O(log2n)
如图所示:
下面我们来看C语言代码:
#include<stdio.h>
非递归实现:
void Binarysearch(int *arr, int len, int k)
{
int left = 0;
int right = len - 1;
int mid;
while (left <= right)
{
mid = left + (right - left) / 2; // (防止数字过大时超出int所表示的范围) mid=(left+right)/2
if (k == arr[mid])
{
printf("找到了\n");
break;
}
else if (k > arr[mid])
{
left = mid + 1;
}
else
{
right = mid - 1;
}
}
if (left > right)
{
printf("没找到\n");
}
}
递归实现:
void Binarysearch1(int *arr, int len, int k, int left, int right)
{
if (left <= right)
{
int mid = left + (right - left) / 2;
if (k == arr[mid])
{
printf("找到了\n");
}
else if (k > arr[mid])
{
left = mid + 1;
Binarysearch1(arr, len, k, left, right);
}
else
{
right = mid - 1;
Binarysearch1(arr, len, k, left, right);
}
}
else
{
printf("没找到\n");
}
}
下面我们看C++代码实现:
#include<iostream>
using namespace std;
//这里使用了模板,可对所有的数据类型进行查找
template<typename T>
int compare(const T a,const T b)
{
if (a > b)
{
return 1;
}
if (a < b)
{
return -1;
}
return 0;
}
typedef char * ptr;
template<>
int compare<char *>(const ptr a, const ptr b)
{
if (strcmp(a,b)>0)
{
return 1;
}
if (strcmp(a,b)<0)
{
return -1;
}
return 0;
}
template <typename T, typename L, typename PRE>
int Binarysearch(T a, L val, int left, int right, PRE compare)
{
if (left>right)
{
return -1;
}
while (left <= right)
{
int mid = (right - left+1) / 2 + left;
if (compare(val, a[mid]) == 1)
{
left = mid + 1;
}
if (compare(val, a[mid]) == -1)
{
right = mid - 1;
}
if(compare(val, a[mid]) == 0)
{
return mid;
break;
}
}
return -1;
}