目录
推荐:部分C语句可参考博客(【简述C语言分支循环语句】http://t.csdnimg.cn/3jyCt)。
引言:经过对数组的初步学习,我们已经认识到数组的基本概念,(相关请看【浅浅理解C语言之数组大佬】http://t.csdnimg.cn/nwLja)。接下来,我们需要联系来巩固这部分知识,以便后期更加深入的学习(文末有彩蛋~)。感谢各位大佬指点......
一、什么是二分查找
二分查找也叫做折半查找,二分查找是查找有序元素(注意:必须是有序元素)列的一种算法,它的目的在于更加节约时间和空间,结果是如果查找的元素存在,则返回其位置,否则返回NULL。
比如存在1——100的数字,我们需要找到40这个元素,你每次输入一个数字,我告诉你它大了,小了,正确。
最无脑的方法就是从1开始猜:第一次:1,小了;
第二次:2,小了;
......
第四十次:40,正确;
这个方法确实可以得到正确答案,但是,不可否认,它存在的弊端很明显,如果我的范围给到了100000,难道我们还是从1开始比较吗,它会耗费大量时间和空间。这个时候二分查找就脱颖而出了,就像它的别名折半查找。需要找到40这个元素:第一次:50,大了;
第二次:25,小了;
第三次:37,小了;
第四次:43,大了;
第五次:40,正确;
两种查找方式优劣显而易见,第一种方式需要排查40次,且存在弊端;第二种方式仅仅需要5次排查,且没有范围限制,对时间和空间都是一种节约。
二、代码实现
#include<stdio.h>
int main()
{
int arr[100]={1 ,2,3,4,5, 6 ,7 ,8 ,9 ,10 ,11 ,12 ,13 ,14 ,15 ,16 ,17 ,18 ,
19 ,20 ,21 ,22 ,23 ,24 ,25 ,26 ,27 ,28 ,29 ,30, 31, 32 ,33 ,34 ,35 ,36 ,
37 ,38 ,39 ,40 ,41 ,
42 ,43 ,44, 45 ,46 ,47 ,48 ,49 ,50 ,
51 ,52 ,53 ,54 ,55 ,56 ,57 ,58 ,59 ,60 ,61, 62, 63, 64, 65, 66, 67,
68 ,69 ,70 ,71 ,72 ,73 ,74 ,75 ,76 ,77 ,78 ,79 ,80 ,81 ,82 ,83 ,84 ,
85 ,86 ,87 ,88 ,89 ,90 ,91 ,92 ,93 ,94 ,95 ,96 ,97 ,98, 99,100};//数组初始化
int k=39;//需要查找的元素
int sz=sizeof(arr)/sizrof(arr[0]);//数组大小
int flag=0;//标志符
int left=0;//第一个元素下标
int right=sz-1;//最后一个元素的下标
while(left<=right)//当左下标>右下标时退出循环
{
int mid=left+(right-left)/2;//取平均值
if(arr[mid]<k)
{
left=mid+1;
}
else if(arr[mid]>k)
{
right=mid-1;
}
else
{
flag=1;
printf("找到了,下标是:%d",mid);
break;
}
}
if(flag==0)
{
printf("找不到\n");
}
return 0;
}
三、分析代码
if(arr[mid]<k)
{
left=mid+1;
}
判断mid为下标的元素是否小于元素k
如果小于,则下一次循环left=mid+1,下一次的范围左端变为mid+1
else if(arr[mid]>right)
{
right=mid-1;
}
判断mid为下标的元素是否大于元素k
如果大于,则下一次循环right=mid-1,下一次的范围右端端变为mid-1
彩蛋:游戏之猜数字
(注:这个游戏运用到二分查找的方法,以便我们对它的理解更加清晰)
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void menu()
{
printf("**********************\n");
printf("***1.play****2.exit***\n");
printf("**********************\n");
}
void game()
{
int ret = 0;
int guess = 0;
ret = rand() % 100 + 1;//1——100
srand((unsigned int)time(NULL));//时间戳
while (1)
{
printf("请输入你猜的数字:");
scanf("%d", &guess);
if (ret < guess)
printf("猜大了\n");
else if (ret > guess)
printf("猜小了\n");
else
{
printf("猜对了\n");
break;
}
}
}
#include<stdio.h>
int main()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menu();
printf("请选择>: ");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 2:
printf("退出游戏");
break;
default:
printf("选择错误");
break;
}
}while (input);
return 0;
}