二分查找是一种简单高效的查找算法。其思想在生活中广泛应用,比如从图书馆书架上查找书,查字典,测量领域中热电偶温度补偿等。
1. 二分法适用条件
被查找序列存储在线性表中;
被查找序列是有序的(非递增或非递减)。若被查找序列不是有序的,且仅查找一次,可直接用遍历方式查找;若需要查找多次,可通过排序算法先对其进行排序,再进行二分查找。
2. 二分查找--C语言实现
二分查找可以用循环和递归两种方式实现
#include
typedef int DataType;
typedef unsigned int uint32;
typedef int int32;
#define SEARCH_LIST_SIZE (8)
int32 BinarySearch(DataType* plist, uint32 len, DataType item); //循环方式
int32 BinarySearchRecur(DataType* plist, uint32 len, DataType item); //递归方式
int main(int argc, char *const argv[])
{
int32 ret = 0;
DataType list[SEARCH_LIST_SIZE] = {1,2,3,4,5,6,7,8};
if((ret = BinarySearchRecur(list, SEARCH_LIST_SIZE, 2)) != -1)
{
printf("Item is found, %d\n", ret);
}
else
{
printf("Do not find\n");
}
}
/*----------------------------------------------------------------------
* Function: int BinarySearch(DataType * plist, uint32 len, DataType item)
* Discription: 二分查找(循环方式)
* Inputs: plist, 指向被查找有序序列的指针;
* len, 被查找序列长度;
* item, 被查找数据
* Outputs: none
* return: -1, 未找到;
* -2, 输入参数异常;
* 其他, 被查找元素对应的数组下标
* ---------------------------------------------------------------------*/
int32 BinarySearch(DataType* plist, uint32 len, DataType item)
{
uint32 icnt = 0;
int32 min = 0, mid = 0, max = len-1; //需定义为有符号类型
if(plist == NULL)
{
return -2;
}
else
{
while(min <= max)
{
mid = (min + max)/2;
if(plist[mid] < item)
{
min = mid + 1;
}
else if(plist[mid] > item)
{
max = mid - 1;
}
else
{
return mid;
}
}
return -1;
}
}
/*----------------------------------------------------------------------
* Function: BinarySearchRecur(DataType* plist, uint32 len, DataType item)
* Discription: 二分查找(递归方式)
* Inputs: plist, 指向被查找有序序列的指针;
* len, 被查找序列长度;
* item, 被查找数据
* Outputs: none
* return: -1, 未找到;
* -2, 输入参数异常;
* 其他, 被查找元素对应的数组下标
* ---------------------------------------------------------------------*/
int32 BinarySearchRecur(DataType* plist, uint32 len, DataType item)
{
int32 min = 0, mid = 0, max = len-1; //定义为有符号类型
if(plist == NULL)
{
return -2;
}
else
{
while(min<=max)
{
mid = (min + max) / 2;
if(plist[mid] < item)
{
min = mid + 1;
BinarySearchRecur(&plist[min], max-min+1, item);
}
else if(plist[mid] > item)
{
max = mid - 1;
BinarySearchRecur(&plist[min], max-min+1, item);
}
else
{
return mid;
}
}
return -1;
}
}
3. 注意
二分查找的时间复杂度为
。
查找有序序列端点处元素时迭代次数最大;
n个元素组成的有序序列,从中查找元素,迭代次数并不是不大于
,有可能迭代
次。
二分查找实现时一定要注意结束条件,循环变量的数据类型。