题目描述:
在一个整型的有序数组中查找某个数字,若找到了就返回当前元素位置,找不到则返回 - 1。
题目分析:
在数组中找到某个值,我们首先想到的方法可能是直接顺序遍历,这是最简单的方法,但是效率不一定高。如果当前给定数组是乱序的,我们只能通过挨着遍历的方法查找某个数。
但当前数组是一个有序数组,我们是否有效率更高的方法呢?这就要介绍一下“折半查找”
主要思想:
折半查找:先通过计算数组的元素个数,找到数组的中间位置。然后将目标数字与数组的中间元素进行比较,若目标数字比它小则在它的左部分按折半查找继续,若目标数字比它大则在它的右部分按折半查找继续,直至到结果,输出位置或者-1。(位置=下标+1)
代码实现思想:
int bin_search(int arr[], int key, int sz) //arr传入数组,key目标值,sz数组元素个数
{
int left = 0; //定义左边下标
int right = sz - 1; //定义右边下标
while (left <= right) //循环条件
{
if (key > arr[(left + right) / 2]) //目标值>中间值
{
left = (left + right) / 2 + 1; //向右半边查找,左边坐标更新
}
else if (key < arr[left + (right - left) / 2]) //目标值<中间值
{
right = left + (right - left) / 2 - 1; //向左半边查找
}
else //目标值=中间值
{
return (left + (right - left) / 2 + 1); //返回下标值+1
}
}
return -1; //while 循环结束未找到,则返回-1
}
解题完整代码:
通过对以上思想的理解,我们便很容易应用到这道题目上。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdlib.h>
#include <stdio.h>
#define N 10
int bin_search(int arr[], int key, int sz) //折半查找方法
{
int left = 0;
int right = sz - 1;
while (left <= right)
{
if (key > arr[(left + right) / 2])
{
left = (left + right) / 2 + 1;
}
else if (key < arr[left + (right - left) / 2])
{
right = left + (right - left) / 2 - 1;
}
else
{
return (left + (right - left) / 2 + 1);
}
}
return -1;
}
int main()
{
int i = 0;
int k = 0;
int sz = 0;
int a[N] = { 0 };
printf("请输入%d个数:", N);
for (i = 0; i < N; i++)
{
scanf("%d", &a[i]);
}
sz = sizeof (a) / sizeof (a[0]);
printf("\n请输入想查找的数:");
scanf("%d", &k);
int ret = bin_search(a, k, sz); //方法调用
if (ret >= 0)
{
printf("\n你想要的数在第%d位!\n", ret);
}
else
printf("\n数组中无此数!\n");
return 0;
}
执行结果与简单说明:
关注博主,有更多精彩的内容哦~