二分查找:
- 获取查找区域的中间位置。
- 若中间位置的数据就是要找的值,则返回true。若要找的值 小于 中间位置的数据,则往左边查找。若要找的值 大于 中间位置的数据,则往右边查找。
- 重复1和2,若没有要找的值,则返回false。
注:二分查找的要求:数据有序(即已排好序)。
时间复杂度:最好情况 O(1),最坏情况 O(logn),平均情况 O(logn)
- 每次找中间位置,每次查找范围减半,查找次数最多logn,因此总时间约 O(logn)。
- 最好情况,是第一个中间位置就是要找的值,时间O(1)。
空间复杂度:【迭代】O(1),【递归】 O(logn)
- 【迭代】只重复使用存储中间位置数据的空间,不随数据量变动而变动,因此空间使用是常量O(1)。
- 【递归】需使用栈存储递归时的中间位置数据,最多查找次数logn,空间使用约 O(logn) 。
C代码实现:
【迭代】
int search(int *array, int length, int data) // binary search
{
// 起始索引,结束索引,中间位置索引
int start = 0, end = length - 1;
int midindex = start + ceil((end - start ) / 2);
// 索引号越界,退出循环
while(midindex >= 0 && midindex <= end)
{
// 找到匹配的值,返回1(true)
if(array[midindex] == data) return 1;
// 找的值比中间值小,往左边找,结束索引为中间位置前一位
if(array[midindex] > data) end = midindex - 1;
// 找的值比中间值大,往右边找,开始索引为中间位置后一位
else start = midindex + 1;
// 循环找下一个中间位置
midindex = start + ceil((end - start ) / 2);
}
// 没找到,返回0(false)
return 0;
}
【递归】
int search2(int *array, int start, int end, int data) // binary search (recursion)
{
// 获取中间位置索引
int midindex = start + ceil((end - start ) / 2);
// 索引号越界,即没找到,返回0(false)
if(midindex < 0 || midindex > end) return 0;
// 找到值,返回1(true)
if(array[midindex] == data) return 1;
// 要找的值 比中间值小,往左边递归查找
if(array[midindex] > data) search2(array, 0, midindex - 1, data);
// 要找的值 比中间值大,往右边递归查找
else search2(array, midindex + 1, end, data);
}
完整代码:(binarysearch.c)
#include <stdio.h>
#include <math.h>
int search(int *, int, int); // binary search
int search2(int *, int, int, int); // binary search (recursion)
void traverse(int *, int); // show element one by one
int main(void)
{
int arr[] = {1,2,3,5,6,8,9};
int n = sizeof(arr) / sizeof(int);
traverse(arr, n);
printf("[no recursion] find '8' (1:true, 0:false): %d\n", search(arr, n, 8));
printf("[ recursion ] find '8' (1:true, 0:false): %d\n", search2(arr, 0, n, 8));
printf("[no recursion] find '4' (1:true, 0:false): %d\n", search(arr, n, 4));
printf("[ recursion ] find '4' (1:true, 0:false): %d\n", search2(arr, 0, n, 4));
return 0;
}
int search(int *array, int length, int data) // binary search
{
int start = 0, end = length - 1;
int midindex = start + ceil((end - start ) / 2);
while(midindex >= 0 && midindex <= end)
{
if(array[midindex] == data) return 1;
if(array[midindex] > data) end = midindex - 1;
else start = midindex + 1;
midindex = start + ceil((end - start ) / 2);
}
return 0;
}
int search2(int *array, int start, int end, int data) // binary search (recursion)
{
int midindex = start + ceil((end - start ) / 2);
if(midindex < 0 || midindex > end) return 0;
if(array[midindex] == data) return 1;
if(array[midindex] > data) search2(array, 0, midindex - 1, data);
else search2(array, midindex + 1, end, data);
}
void traverse(int *array, int length) // show element one by one
{
printf("elements(%d): ", length);
for(int k = 0; k < length; k++)
{
printf("%d ", array[k]);
}
printf("\n");
}
编译链接: gcc -o binarysearch binarysearch.c
执行可执行文件: ./binarysearch