初级系列9.折半查找
折半查找
问题描述
N个有序整数数列已放到一位数组中,利用二分查找法查找整数m在数组中的位置 若找到,输出其下标值,反之,则输出"Not be found!"
问题分析
二分查找法(折半查找),其本质是分治算法的一种,分治算法即是分而治之即将较大规模的问题分解成几个较小规模的问题,这些子问题互相独立且与原问题相同,通过对较小规模问题的求解达到对整个问题的求解,当将问题分解成两个较小问题求解时的分治方法称为二分法,二分查找法只适用于有序序列
二分查找的基本思想:每次查找前先确定数组中待查的范围:假设指针low和high(low<high)
分别指示待查范围的下界和上界,指针mid指示区间的中间位置
即mid = (low + high) / 2,把m与中间位置(mid)中元素的值进行比较
如果m的值大于中间位置元素中的值,则下一次的查找范围放在中间
位置之后的元素中,反之,下一次的查找范围放到中间位置之间的元素中
直到low > high 查找结束
算法设计
定义三个指针变量:low,high,mid 此外还需要一个变量k记录下标,利用变量k的值判断整数m是否是在所给出的数组中
//要查找的数m为21
low mid high
| | |
5 13 19 21 37 56 64 75 80 88 92
low mid high
| | |
5 13 19 21 37 56 64 75 80 88 92
mid
|
low high
| |
5 13 19 21 37 56 64 75 80 88 92
#include <stdio.h>
#define N 10
int main(void)
{
int i, a[N] = {-3, 4, 7, 9, 13, 45, 67, 89, 100, 180};
int low = 0, high = N-1, mid, k = -1, m;
printf("a数组找那个的数据如下: \n");
for (i = 0; i < N; i++) {
printf("%d ", a[i]); /* !<输出数组中原数据序列 */
}
printf("\n");
printf("Enter m: ");
scanf("%d", &m); /* !< 由键盘输入要查找的整数值 */
while (low <= high) { /* !< 继续查找的控制条件 */
mid = (low + high) / 2; /* !< 确定指针mid的位置 */
if (m < a[mid]) {
high = mid - 1;
}
else {
if (m > a[mid]) {
low = mid + 1;
}
else {
k = mid;
break; /* !< 找到所要查找的元素便跳出循环 */
}
}
}
if (k >= 0) {
printf("m = %d, index = %d\n", m, k);
}
else {
printf("Not be found!\n");
}
}