C语言——二分查找与猜数字游戏

12 篇文章 3 订阅
订阅专栏
文章详细介绍了二分查找算法的思想、条件及实现过程,并通过代码示例展示了如何在一个有序数组中应用二分查找。接着,文章提出了猜数字游戏,解释了游戏逻辑,并提供了游戏的代码框架,包括主函数和游戏函数,游戏基于随机数生成和用户输入进行交互。
摘要由CSDN通过智能技术生成

二分查找

题目: 在一个有序数组中查找具体的某个数字n。

首先我们先定义一个1···10的数组 ,如果7为我们要查找的数字,编写代码如下

#include <stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	//  下标          0 1 2 3 4 5 6 7 8 9
	int k = 7;//k是要查找的数字
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
     //sz为数组元素个数
	int flag = 0;//
	for (i = 0; i < sz; i++)
	{
		if (k == arr[i])
		{
			flag = 1;
			printf("找到了,下标是:%d\n", i);
			break;
		}
	}
	if (flag == 0)
		printf("找不到\n");

	return 0;
}

但是这个代码的效率比较低,需要循环多次,所以我们需要用一个效率较高的方法:二分查找又叫 (折半查找)

二分查找的思想

给你一个有序的序列,取中间元素和目标元素进行对比,取其中的一半,丢弃另一半,快速缩小目标元素所在的位置。主要思想还是:快速缩小目标元素所在的区间。

二分查找的条件

1.序列必须是有序的,升序或者降序都可以
2. 序列必须是顺序存储元素的,顺序存储元素主要是可以快速的获取中间元素(可以通过下标来找到元素)

二分查找的实现过程

分析:假设我们要找的数字为7,在查找过程中要用下标进行查找,此时我们定义左下标为left,右下标为right,中间元素下标为mid,(left+right)/2=mid。当第一次查找没有找到时,从中间下标向左或向右缩短查找范围继续查找,直到找到为止。

  • 以数字7为例:第一次查找(left+right)/2=(0+9)/2=4,下标为4找到的数字为5,此时并没有找到;第二次查找,因为数字5小于数字7,所以mid+1=left,right不变,向右查找,此时(left+right)/2=(5+9)/2=7,下标为7,找到的数字为8,并没有找到;第三次查找,因为数字8大于数字7,所以mid-1=right,左下标不变,向左查找,此时(left+right)/2=(5+6)/2=5,下标为5,找到的数字为6,第四次查找,因为6小于7,所以向右查找,(left+right)/2=(6+6)/2=6,下标为6,找到的数字为7。
    在这里插入图片描述

代码举例

#include <stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	// 下标       0 1 2 3 4 5 6 7 8 9
	int k = 7;//k是要查找的数字
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	//折半查找(二分查找),前提是数组有序
	int left = 0;
	int right = sz - 1;

	int flag = 0;
	while (left<=right)
	{
		int mid = (left + right) / 2;
		if (arr[mid] < k)
		{
			left = mid + 1;
		}
		else if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else
		{
			printf("找到了,下标是:%d\n", mid);
			flag = 1;
			break;
		}
	}
	if (flag == 0)
		printf("找不到\n");

	return 0;
}

如果left是一个很大的数,right也是一个很大的数,left+right超出整形能表达的最大值,数据溢出,此时(left+right)/2所求的就不是最大值了这时要怎么办呢?
我们让多出的部分除以二在平分,如图所示
在这里插入图片描述

代码修改

#include <stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	//            0 1 2 3 4 5 6 7 8 9
	int k = 7;//k是要查找的数字
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	//折半查找(二分查找),前提是数组有序
	int left = 0;
	int right = sz - 1;

	int flag = 0;
	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
		{
			printf("找到了,下标是:%d\n", mid);
			flag = 1;
			break;
		}
	}
	if (flag == 0)
		printf("找不到\n");

	return 0;
}

猜数字游戏

游戏说明

1.电脑生成一个1~100的的随机数
2.猜数字
猜大了 就告诉你:猜大了
猜小了 就告诉你:猜小了
猜对了 就告诉你:恭喜你,猜对了

猜数字游戏思想

  • 首先要打印一个菜单,选择开始游戏还是退出游戏
  • 其次,游戏应该可以玩完一局之后玩一局,为循环进行,利用循环语句构建框架

代码实现

打印菜单

void menu()
{
	printf("*****************************\n");
	printf("*********   1. play  ********\n");
	printf("*********   0. exit  ********\n");
	printf("*****************************\n");
}

打印结果
在这里插入图片描述

打印主函数

int main()
{
	int input = 0;
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("猜数字\n");
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误\n");
			break;
		}
	} while (input);
	return 0;
}

此时游戏过于简单,选择1要开始游戏,所以我们定义一个游戏函数game()

打印游戏函数

游戏第一步:生成随机数
rand()函数为生成随机数函数,头文件为<stdlib.h>
rand会返回一个0~327637之间的数
使用rand()要搭配srand() 一起使用,srand()是设置随机数生成器,一般用时间戳作为时间的种子,所以使用time函数来获取时间,然后将time函数转换为(unsigned)类型在传给srand函数
在这里插入图片描述
在这里插入图片描述

void game()
{
	//1. 生成随机数
	int ret = rand() % 100 + 1;//0~99+1-->1~100
	//2. 猜数字
	int guess = 0;
	while (1)
	{
		printf("请猜数字:>");
		scanf("%d", &guess);
		if (guess < ret)
		{
			printf("猜小了\n");
		}
		else if (guess > ret)
		{
			printf("猜大了\n");
		}
		else
		{
			printf("恭喜你,猜对了\n");
			break;
		}
	}
}

整体代码演示

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

void menu()
{
	printf("*****************************\n");
	printf("*********   1. play  *******\n");
	printf("*********   0. exit  ********\n");
	printf("*****************************\n");
}
//
//rand函数会返回一个0~32767之间的随机数
//
//时间戳

void game()
{
	//1. 生成随机数
	int ret = rand() % 100 + 1;//0~99+1-->1~100
	//2. 猜数字
	int guess = 0;
	while (1)
	{
		printf("请猜数字:>");
		scanf("%d", &guess);
		if (guess < ret)
		{
			printf("猜小了\n");
		}
		else if (guess > ret)
		{
			printf("猜大了\n");
		}
		else
		{
			printf("恭喜你,猜对了\n");
			break;
		}
	}
}

int main()
{
	int input = 0;
	//设置了随机数的生成器
	srand((unsigned int)time(NULL));
    //给srand传一个时间戳,是生成的数字足够随机
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误\n");
			break;
		}
	} while (input);
	return 0;
}

游戏效果演示
在这里插入图片描述

二分查找实现数小游戏C语言)你注意到二分查找二十年未曾发现的bug了吗?
来学编程吧的博客
03-18 6209
今天为大家介绍二分查找算法,并简单写一个猜数字的小游戏,小沐先要跟各位铁子说,你可能会二分查找,但你写的真的对吗?😉😉😉接下来我们写一个数小游戏来说明
通过C语言实现二分查找
Jabok的博客
09-13 2002
二分查找基本思想是将n个元素分成大致相等的两部分,取a [n/2]与x做比较,如果x=a [n/2],则找到x,算法中止;如果xa [n/2],则只要在数组a的右半部搜索x. 时间复杂度即是while循环数。 折半查找法 也称为二分查找法,它充分利用了元素间的序关系,采用分治策略,可在最坏的情况下用O (log n)完成搜索任务。
c语言 数组形参 二分查找 随机种子 游戏
漫鱼
12-15 466
数组做形参 如果是传值会拷贝,如果是数组就不会拷贝了而是把第一个元素的地址传入,这也是定义形参不需要定义大小的原因。本质上是应该定义 int* ,定义成a[]只是语法上好看。因此在函数中计算传入数组的大小是不存在的!! 解决办法只能是增加参数 int size; 在如下二分查找代码里可以看出 #include &lt;stdio.h&gt; int binary_search(int ar...
二分查找猜数字游戏思路详解、选择语句与循环句练习
m0_73067372的博客
08-19 1519
1、二分查找 2、猜数字游戏思路详解 3、选择语句与循环语句练习
循环语句的简单应用(二分查找猜数字游戏
aaronlanni的博客
07-22 916
在写代码之时,正确的使用循环语句,可以极大的提高我们的效率,增加代码的可读性,为别人以及自己的学习,带来极大的方便。 今天,利用C语言中的循环语句,简单的实现我们的折半查找(二分查找:在有序数组中的查找)以及猜数字游戏
C语言经典例题(猜数字游戏,二分查找,模拟登陆(字符串的比较),判读字符类型并转化输出)
qq_41152046的博客
10-08 306
1.完成猜数字游戏。0–100 play_game() { int ret = 0; int guess = 0; ret = rand()%100+1; printf("猜数字开始,请输入0-100之间的数字:\n"); while (1) { scanf("%d", &guess); if (ret == guess) { printf("恭喜你对了\...
C语言实现猜数字游戏!(图解超级简单。)
qq_27183803的博客
11-19 2154
最简单的猜数字实现,比你想象的要简单的多。
查找与排序——二分查找
m0_48660343的博客
06-01 637
用递归法实现二分查找二分查找的思路用递归法写出二分查找的代码时空复杂度 二分查找的思路 二分查找也称为折半查找(binary search),适用于顺序存储结构的线性表,且表中元素是有序排列的情况。 对于一个顺序排列的数组,当确定待查找元素的大小没有超出查找区间时,每循环取当前区间中间的元素与目标值比较,根据以下三种比较结果判断跳出循环或更新左右边界: 目标值 = 中间元素 此时正好在在当前区间的中间找到目标值,查找成功,跳出循环。 目标值 < 中间元素 表示此时目标值在以中间元素为界的左区
C语言——职员管理系统.pdf
06-13
6. **查询模块**:根据用户提供的工资卡号或姓名搜索特定的职员信息,需要实现高效的查找算法,如线性搜索或二分搜索。 7. **退出模块**:结束程序执行,释放分配的资源。 在数据结构方面,系统可能采用了结构体来...
算法导论系列】分治策略(1)——二分查找与时间复杂度递归式求解
dingzr2001的博客
06-15 2672
介绍了二分查找,并由此引出时间复杂度递归式求解的三种方法——代入法、递归树法、主方法
MFC编写的二分法猜数字游戏
05-12
顾名思义即可。有每猜数字的记录,有动态变化的标题栏图标。原创。纯属娱乐,虽然技术含量低了一点。囧囧。
二分法 做个猜数字游戏
gskksg的博客
04-23 425
生成随机数
二分查找 ----- Leetcode-374. 猜数字大小
qq_36098284的博客
09-06 404
题目参考:https://leetcode-cn.com/problems/guess-number-higher-or-lower/description/ 我们正在玩一个猜数字游戏游戏规则如下: 我从 1 到 n 选择一个数字。 你需要我选择了哪个数字。 每错了,我会告诉你这个数字是大了还是小了。 你调用一个预先定义好的接口 guess(int num),它会返回 3 个可能的结...
猜数字游戏c语言二分法,JavaScript实现猜数字游戏
weixin_33982454的博客
05-22 689
本博文源于js基础,旨在讨论如何实现随机数的小游戏。题目重现随机生成一个[0,100]区间的数字,不断重复用户输入,直到用户输入对为止。实现原理先用Math.random生成一个数字,欲得到[a,b]区间的随机整数,可采用以下公式:parseInt(Math.random()*(b-a+1))+a;举个例子:得到[3,8]parseInt(Math.random()*6)+3;然后循环里,多分支...
使用while循环猜数字(python)
最新发布
2201_75813676的博客
09-28 2513
设置一个1-100的随机整数变量,通过while循环,配合input语句,判断输入的数字是否等于随机数。2.每一不中,还会提示大或小。1.无限机会,知道中位置。3.完数字后,提示了几
C语言二分法猜数字游戏
萌新的博客
06-05 4561
猜数字 题目: 输入n(0<n<100), 想让程序到的值 程序通过二分法不断缩小测范围, 直到中n 例如n = 39 程序第一测50, 判断数值太大 第二测25, 判断数值太小 第三测37 判断数值太小 43 大 40 大 38 小 39 正确 代码附上: #include <stdio.h> #include <stdlib.h> #define X 0 //初始左边界 #define Y 100
二分法编写猜数字游戏(含:电脑随机数,和用户自己想的数字)python
rosediver的博客
04-14 5818
二分法编写猜数字游戏(含:电脑随机数,和用户自己想的数字)python ​对于区间[a,b]上连续不断且f(a)·f(b)<0的函数y=f(x),通过不断地把函数f(x)的零点所在的区间一分为二,使区间的两个端点逐步逼近零点,进而得到零点近似值的方法叫二分法。 生成随机数的函数为random.randint(min,max),其中min和max分别是随机数的最大值和最小值。 用二分法用户所想的数:当小数部分不为0时,就给整数部分+1
简单的猜数字游戏二分查找,杨辉三角
L_XRUI的博客
07-01 1325
猜数字游戏: #include #include #include void Print_menu() { printf("********请选择:**********\n"); printf("********1:开始游戏********\n"); printf("********0:退出游戏********\n"); } void Guess_num() { int input
C语言之二分猜数字游戏
weixin_30569001的博客
08-06 188
#include <stdio.h>#include <windows.h>#include<string.h>int main() { int oldprice, price = 0, i = 0; printf("请首先设置商品的真实价格:"); scanf("%d", &oldprice); system("cls"); pr...
写文章

热门文章

  • 浅谈ChatGPT(人工智能) 33920
  • 【Docker】Docker 仓库管理和Docker Dockerfile 25043
  • 动态通讯录——C语言【详解+全部码源】 22409
  • 【Docker】Docker Compose,yml 配置指令参考的详细讲解 21793
  • 【Docker】Docker中 的AUFS、BTRFS、ZFS、存储池概念的详细讲解 19845

分类专栏

  • 进阶C语言 12篇
  • 七七的闲谈 50篇
  • Java.SE 10篇
  • python入门 17篇
  • 初阶C语言 12篇

最新评论

  • 数据库世界的点滴成长:从初学者到实战经验

    CSDN-Ada助手: 推荐 MySQL入门 技能树:https://edu.csdn.net/skill/mysql?utm_source=AI_act_mysql

  • 数据库世界的点滴成长:从初学者到实战经验

    新梦空间: 博主文章很详细,感谢分享,期待博主持续带来更多优质好文。

  • 数据库世界的点滴成长:从初学者到实战经验

    进击的小C: 博主的写作风格简洁明了,让人一目了然。文章内容丰富,涵盖了很多实用的知识点。非常感谢博主的分享,期待博主能够继续输出这样优质的好文。

  • 数据库世界的点滴成长:从初学者到实战经验

    想你依然心痛: 数据库世界的点滴成长:从初学者到实战经验,望回

  • 数据库世界的点滴成长:从初学者到实战经验

    猫佛佛: 数据库世界的点滴成长:从初学者到实战经验

最新文章

  • 数据库世界的点滴成长:从初学者到实战经验
  • 腾讯云AI代码助手:智能编程的未来之窗
  • 【文心智能体大赛】迎接属于你的休闲娱乐导师!
2024年7篇
2023年98篇
2022年4篇

目录

目录

评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辭七七

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或 充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

玻璃钢生产厂家商场的美陈入什么费用金昌玻璃钢动物雕塑定做湖北玻璃钢卡通雕塑设计东莞泡沫玻璃钢雕塑艺术红色革命主题玻璃钢雕塑供应商武义广场玻璃钢雕塑合肥户内玻璃钢雕塑供应商甘肃景区玻璃钢雕塑价格革命主题玻璃钢雕塑厂家现货陕西人物玻璃钢雕塑优势玻璃钢卡通水果雕塑加工小品玻璃钢卡通雕塑报价表深圳led发光玻璃钢雕塑制作厦门rtm法玻璃钢雕塑定制成品玻璃钢花盆哪家好湘西玻璃钢造型雕塑河北玻璃钢雕塑售价哈尔滨玻璃钢桃子雕塑玻璃钢雕塑的优势季节性商场美陈报价广东户外商场美陈价格长沙玻璃钢泡沫雕塑户外景观玻璃钢雕塑厂家联系方式现代创意水景雕塑玻璃钢商场夏季美陈制作金华玻璃钢雕塑批发玻璃钢雕塑深圳黑河玻璃钢雕塑价格山西阳泉市园林雕塑玻璃钢佛山玻璃钢人物雕塑定做香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化