二分查找也叫作折半查找,可以在已经有序的线性序列中定位指定数据的位置。
如果直接使用线性查找的话时间复杂度为O(n)。而二分查找的时间复杂度为O(lgn)。
实现部分在indexof函数,参数p为有序序列的指针,n为序列长度,x为要查找的值
定义两个变量min和max,分别为查找区间下标的最小值和最大值
每次循环都取查找序列中的中间值,如果大于目标值就把下标最小值设置为中间的后一个,如果小于目标的话就把下标最大值设置为中间的前一个,否则就正好相等,返回当前下标。
看代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int *input(int n)
{
int *p = (int*)malloc(n * sizeof(int));
while (n--)
{
scanf("%d", p + n);
}
return p;
}
int output(int *p, int n)
{
while (n--)
{
printf("%d ", p[n]);
}
printf("\n");
return 0;
}
int fn(int* p, int n)
{
int i = 0, j = n / 2, k = 0;
int* t = (int*)malloc(n * sizeof(int));
while (k < n)
{
if (i == n / 2)
{
t[k] = p[j];
j = j + 1;
}
else if (j == n)
{
t[k] = p[i];
i = i + 1;
}
else if (p[i] < p[j])
{
t[k] = p[i];
i = i + 1;
}
else
{
t[k] = p[j];
j = j + 1;
}
k = k + 1;
}
memcpy(p, t, sizeof(int) * n);
free(t);
return 0;
}
int sort(int* p, int n)
{
if (n == 1)
{
return 0;
}
else
{
sort(p, n / 2);
sort(p + n / 2, n - n / 2);
fn(p, n);
}
return 0;
}
int indexof(int *p, int n, int x)
{
int min = 0, max = n - 1;
while (min < max)
{
if (x < p[(max + min) / 2])
{
max = (max + min) / 2 - 1;
}
else if (x > p[(max + min) / 2])
{
min = (max + min) / 2 + 1;
}
else
{
min = (max + min) / 2;
while (min)
{
if (x == p[min - 1])
{
min = min - 1;
}
else
{
return min;
}
}
return min;
}
}
return 0;
}
int main(int argc, char *argv[])
{
int n, m;
int *p;
scanf("%d", &n);
p = input(n);
sort(p, n);
output(p, n);
scanf("%d", &m);
printf("%d\n", indexof(p, n, m));
free(p);
return 0;
}