二分查找算法详解:从基础理论到C++实现及猜数游戏应用
创作时间:
作者:
@小白创作中心
二分查找算法详解:从基础理论到C++实现及猜数游戏应用
引用
CSDN
1.
https://blog.csdn.net/Jeaten/article/details/107823781
二分查找,也称为折半查找,是一种高效的查找算法。它要求线性表必须是顺序存储的(数组)结构,而且顺序表中的元素是有序排列的。本文将详细介绍二分查找的原理、步骤及其在C++中的实现,并通过一个猜数游戏来进一步说明二分查找的应用。
二分查找
二分查找的基本思想是每次查找时都从中间位置开始查找。如下图所示,就是一个满足折半查找要求的存储结构:
二分查找的步骤
我们令表中元素按升序排列,则二分查找的步骤为:
- 将中间位置的记录与给定数据进行比较,如果相等,则查找成功
- 否则使用中间位置将表分为两个子表
- 若给定数据大于中间位置元素,则从中间位置以后到结尾位置构成的子表中进行二分查找
- 若给定数据小于中间位置元素,则从开始位置到中间位置构成的子表中进行二分查找
- 重复以上过程,若找到,则查找成功;若查找到子表不存在,则给定数据不在表中
我们以在有序表 8,12,20,68,76,89,91,120,155 中查找 68 为例说明以上过程(图中 s 表示开始查找的位置,e 表示结尾查找的位置,mid 表示中间位置,我们令 mid = ⌊(s+e)/2⌋):
- 表长为
9,中间位置为4,将68与第4号的数据进行比较,不相等,68小于76,在左边子表中进行查找:e变为3
- 表长为
4,中间位置为1,将68与第1号元素进行比较,不相等,68大于12,在右边子表中进行查找,s变为2
- 表长为
2,中间位置为2,将68与第2号元素进行比较,不相等,68大于12,在右边子表中进行查找,s变为3
- 表长为
1,中间位置为3,将68与第3号元素进行比较,相等,数据找到,返回数据位置
以上查找过程通过 4 次查找到了想要查找的数据。
二分查找的C++实现
以下是上述查找过程的C++代码实现:
#include <iostream>
using namespace std;
int s,e;
int bin_search(int arr[],int s,int e,int data){
if(s<=e){
int mid=(s+e)/2;
if (arr[mid]==data){
return mid;
}else if(data<arr[mid]){
e=mid-1;
bin_search(arr,s,e,data);
}else{
s=mid+1;
bin_search(arr,s,e,data);
}
}else{
return -1;
}
}
int main(){
int arr[]={8,12,20,68,76,89,91,120,155};
s=0,e=8;
cout<<"place="<<bin_search(arr,s,e,68);
return 0;
}
代码运行结果为:
place=3
猜数游戏
通过对二分查找的过程分析我们发现,对于一个数 n,我们采用二叉查找最多需要查找 ⌊log_2n⌋+1 次便可以找到该数。那么假如有一个 1000 以内的一个数,我们最多需要比较 10 次就可以找到这个数。让我们通过一个猜数游戏来体验一下:
#include <iostream>
#define Num 1000
using namespace std;
int choice,s,e,judge;
int arr[Num];
int guess(int s,int e){
if(s<=e){
cout<<"是"<<arr[(s+e)/2]<<"吗(1.是2.不是)?";
cin>>judge;
if(judge==1){
cout<<"哈哈哈,被我猜到了吧!"<<endl;
}else if(judge==2){
cout<<"大了还是小了?(1.大了2.小了)";
cin>>choice;
switch(choice){
case 1:
e=(s+e)/2-1;
guess(s,e);
break;
case 2:
s=(s+e)/2+1;
guess(s,e);
break;
default:
cout<<"输入有误,继续猜啊!\n";
guess(s,e);
break;
}
}else{
cout<<"输入有误,继续猜啊!\n";
guess(s,e);
}
}else{
cout<<"撒谎了还怎么玩游戏呢!\n"<<endl;
}
}
int main(){
for(int i=0;i<Num;i++)arr[i]=i+1;
s=0,e=999;
guess(s,e);
return 0;
}
让我们猜个 999 玩一玩,猜的过程(运行结果)如下:
是500吗(1.是2.不是)?2
大了还是小了?(1.大了2.小了)2
是750吗(1.是2.不是)?2
大了还是小了?(1.大了2.小了)2
是875吗(1.是2.不是)?2
大了还是小了?(1.大了2.小了)2
是938吗(1.是2.不是)?2
大了还是小了?(1.大了2.小了)2
是969吗(1.是2.不是)?2
大了还是小了?(1.大了2.小了)2
是985吗(1.是2.不是)?2
大了还是小了?(1.大了2.小了)2
是993吗(1.是2.不是)?2
大了还是小了?(1.大了2.小了)2
是997吗(1.是2.不是)?2
大了还是小了?(1.大了2.小了)2
是999吗(1.是2.不是)?2
大了还是小了?(1.大了2.小了)2
是1000吗(1.是2.不是)?2
大了还是小了?(1.大了2.小了)2
撒谎了还怎么玩游戏呢!
可以看到我们在第九步猜到了。
本文原文来自CSDN
热门推荐
炒斋 罗汉斋 鲜甜爽口 素菜最好吃的做法
腐竹焖咸肉:一道美味又营养的传统佳肴
腐竹的10种最佳吃法,简单易学
健身的氨基酸怎么使用
当代年轻人的消费新哲学:理性与感性的交织
猫九教你如何挑选靠谱的宠物寄养中心
大花红景天:养生界的宝藏植物
大花红景天:提升免疫力的天然良药
红景天:高原上的“仙赐草”,抗缺氧神器
大花红景天:心血管健康的守护神
永恒纪元战士职业:打架首选,生存无敌
《永恒纪元》战士职业高效升级秘籍🔥
如果你同时喜欢上两个人,一定要选第二个
港式羊腩煲:冬日暖心美味的传统与创新
婆媳关系大挑战:过年回谁家?
婆媳关系中的智慧:东方女英和小孩哥教你搞定家庭矛盾
糖尿病患者能否食用氨基酸补充剂?
农业地膜的分类及作用
古代快递哪家强
中国“包裹”何以腾飞
热情服务的锦旗标语
新电子税局代开增值税发票(自然人篇)
福建香烟市场一手货源揭秘:优质货源与成熟产业链的完美结合
同时被两个人喜欢,应该如何选择(两难抉择的心理困境与解决方案)
选择一款适合自己的马丁靴
生病没食欲?这6道病人家常营养汤,清甜鲜美,既营养又易消化
春节:中华文明的活态传承方式
脂肪酸甲酯(FAME)为生物柴油主要成分 行业发展空间广阔
西藏大花红景天的神奇栽培秘籍
大花红景天:高原反应的天然克星