二分法的应用

请添加图片描述

文章目录

  • 什么是二分法🎮
  • 二分查找的优先级
  • 二分查找的步骤💥
    • 图解演示🧩
  • 代码演示🫕
    • python程序实现🐈‍⬛
    • C程序实现🐕‍🦺
    • C++程序实现🐯
    • Java程序实现🐳
  • 非常规类二分查找🏡
    • 查找有序列表中某数首次出现的位置🫖

什么是二分法🎮

二分法(Bisection method),即一分为二的的方法。数学的零点估计问题中:对于在区间[a,b]上连续不断且满足 f(a) * f(b) <0的函数y=f(x),通过不断地把函数f(x)的零点所在区间二等分,使区间两个端点逐步逼近零点,进而得到零点的近似值的方法。

😎当然,在我们技术人的手中,一般是用来解决有序列表中查找某个元素的问题,属于搜索方法的一种。
😵‍💫简单的来说,就是将答案所在的区间不断缩小为原来的 1/2,直到找到答案。

🎉类似二分法的实例
假如你和朋友在玩猜数字游戏,朋友记录一个数,规定数的范围,你来猜。你每猜一个数,朋友会告诉你这个数大了还是小了,直到你猜出正确答案为止。假如有100个数,你一个一个数猜,你最差的情况需要找100次,如果你使用二分的思想查找,每次折半,最多只需要7次即可猜出答案。

二分查找的优先级

二分查找算法的时间复杂度为O(log n),因此其优先级较高,适合在需要快速查找有序列表中的元素时使用。相比于线性查找算法的时间复杂度为O(n),二分查找算法具有更高的效率,尤其适用于数据量较大的情况。同时,二分查找算法较为简单,易于实现和理解,因此被广泛应用于各个领域的程序设计中。
二分查找的效率虽然高,但只局限于有序列表

二分查找的步骤💥

二分查找的思路是先取中间位置的值进行比较,如果该值等于目标值,则查找成功;否则,如果该值大于目标值,则在左半部分继续查找;如果该值小于目标值,则在右半部分继续查找。不断重复以上步骤,直到找到目标值或者确定目标值不存在为止。

图解演示🧩

在下面这个有序数组中查找数字3
定义三个指针:left、right、mid
这三个指针都是动态的,left 为左边界的下标,right 为右边界的下标,mid=(left+right)/2

在这里插入图片描述
arr[mid]>3,中间值大于目标值,说明右边没有要查找的数,之后范围缩小到左边。
改变右指针right=mid-1在这里插入图片描述
这里 arr[mid] 恰好等于要查找的数,二分结束。
假设要查找的数变为4,那么还需要继续查找,如图在这里插入图片描述
arr[mid]<4,中间值小于目标值,说明左边没有要查找的数,范围再缩小到原来的右边
改变左指针left=mid+1
在这里插入图片描述
arr[mid]=4 就找到了需要查找的数
当左指针 left 大于等于右指针 right 时,二分查找结束,答案可能是找到目标值或者目标值不存在。

代码演示🫕

其中,arr为有序列表,target为需要查找的元素,最终未找到就返回 -1

python程序实现🐈‍⬛

def binary_search(arr, target):left, right = 0, len(arr) - 1while left <= right:mid = (left + right) // 2if arr[mid] == target:return midelif arr[mid] < target:left = mid + 1else:right = mid - 1return -1

定义一个函数binary_search,该函数接受两个参数:一个有序数组 arr 和要查找的目标元素 target

C程序实现🐕‍🦺

#include <stdio.h>// 二分查找函数
int binary_search(int arr[], int left, int right, int target){while (left <= right) // 当left>right时停止查找{int mid = (left + right) / 2; // 计算中间位置if (arr[mid] == target) // 找到目标值{return mid;}else if (arr[mid] < target) // 目标值在右半部分{left = mid + 1;}else // 目标值在左半部分{right = mid - 1;}}return -1; // 没有找到目标值
}int main()
{int arr[] = {1, 3, 5, 7, 9, 11}; // 有序数组int n = sizeof(arr) / sizeof(arr[0]); // 数组长度int target = 5; int index = binary_search(arr, 0, n - 1, target); // 进行二分查找if (index == -1){printf("目标值不存在\n");}else{printf("目标值在数组中的下标为:%d\n", index);}return 0;
}

自己定义一个函数binary_search,接收数组、数组的左右边界下标(或数组元素个数),以及要查找的元素

C++程序实现🐯

#include <iostream>
using namespace std;int binarySearch(int arr[], int l, int r, int x) {if (r >= l) {int mid = l + (r - l) / 2;if (arr[mid] == x) {return mid;}if (arr[mid] > x) {return binarySearch(arr, l, mid - 1, x);}return binarySearch(arr, mid + 1, r, x);}return -1;
}int main() {int arr[] = { 2, 4, 6, 8, 10 };int n = sizeof(arr) / sizeof(arr[0]);int x = 8;int result = binarySearch(arr, 0, n - 1, x);if (result == -1) {cout << "Element not found" << endl;}else {cout << "Element found at index " << result << endl;}return 0;
}

函数binarySearch为二分查找函数,该函数接受一个整数数组,数组的左右边界以及要查找的元素

Java程序实现🐳

public class BinarySearch {int binarySearch(int arr[], int l, int r, int x) {if (r >= l) {int mid = l + (r - l) / 2;if (arr[mid] == x) {return mid;}if (arr[mid] > x) {return binarySearch(arr, l, mid - 1, x);}return binarySearch(arr, mid + 1, r, x);}return -1;}public static void main(String args[]) {BinarySearch bs = new BinarySearch();int arr[] = { 2, 4, 6, 8, 10 };int n = arr.length;int x = 8;int result = bs.binarySearch(arr, 0, n - 1, x);if (result == -1) {System.out.println("Element not found");}else {System.out.println("Element found at index " + result);}}
}

在此示例中定义了一个类BinarySearch,其中包含一个递归函数binarySearch,该函数接受一个整数数组,数组的左右边界以及要查找的元素。

非常规类二分查找🏡

查找有序列表中某数首次出现的位置🫖

如下图中,找到3首次出现的位置(左边界),不难。但要以时间复杂度为 log(N)找到,就要采用二分查找了。
在这里插入图片描述
C程序代码

int Find_Edges(int*nums,int len,double k)
{int left=0,right=len-1;while(left<=right){int mid=(left+right)/2;if(nums[mid]<k)left=mid+1;else if(nums[mid]>k)right=mid-1;}return left;
}int GetNumberOfK(int* nums, int numsLen, int k ) {return Find_Edges(nums,numsLen,k-0,5);
}

上面这段代码将参数 3-0.5 传上去,就可以求出3的左边界,因为传上去的是浮点数,那肯定是找不到的,只能找到距离最近的向上取整的可以找到的数,因为整数除法是向下取整的,所以,mid的值一定是小于等于 (left+right)/2的,所以一定会在 left 位置结束二分查找。

同样,将参数 3+0.5 传上去,就可以求出3的右边界,进而求出这个数组中一共有多少个3,进而解决这篇博客中最后一题C语言笔试训练。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/29925.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue3 - 使用reactive定义响应式数据进行列表赋值时,视图没有更新的解决方案

文章目录 1&#xff0c;问题2&#xff0c;原因3&#xff0c;解决方案一、再封装一层数据&#xff0c;即定义属性名&#xff0c;在后期赋值的时候&#xff0c;对此属性进行直接赋值三、使用数组的splice来直接更改原数组三、使用 ref 来定义数据 1&#xff0c;问题 在Vue 3.0 中…

【VS Code插件开发】通用功能(二)

&#x1f431; 个人主页&#xff1a;不叫猫先生&#xff0c;公众号&#xff1a;前端舵手 &#x1f64b;‍♂️ 作者简介&#xff1a;2022年度博客之星前端领域TOP 2&#xff0c;前端领域优质作者、阿里云专家博主&#xff0c;专注于前端各领域技术&#xff0c;共同学习共同进步…

word横向页面侧面页码设置及转pdf后横线变竖线的解决方案

在处理材料的时候&#xff0c;会遇到同一个文档里自某一页开始&#xff0c;页面布局是横向的&#xff0c;这时候页码要设置在侧面&#xff0c;方法是双击页脚&#xff0c;然后在word工具栏上选择“插入”——>“文本框”——>“绘制竖版文本框”&#xff0c;然后在页面左…

Python-OpenCV中的图像处理-几何变换

Python-OpenCV中的图像处理-几何变换 几何变换图像缩放图像平移图像旋转仿射变换透视变换 几何变换 对图像进行各种几个变换&#xff0c;例如移动&#xff0c;旋转&#xff0c;仿射变换等。 图像缩放 cv2.resize() cv2.INTER_AREAv2.INTER_CUBICv2.INTER_LINEAR res cv2.r…

岩土工程仪器多通道振弦传感器信号转换器应用于桥梁安全监测

岩土工程仪器多通道振弦传感器信号转换器应用于桥梁安全监测 桥梁作为交通运输的重要节点&#xff0c;其安全性一直备受关注。不同于其他建筑物&#xff0c;桥梁所处的环境复杂多变&#xff0c;同时&#xff0c;其所需承受的负荷也相对较大&#xff0c;这就需要对桥梁的安全进…

北京多铁克FPGA笔试题目

1、使用D触发器来实现二分频 2、序列检测器&#xff0c;检测101&#xff0c;输出1&#xff0c;其余情况输出0 module Detect_101(input clk,input rst_n,input data, //输入的序列output reg flag_101 //检测到101序列的输出标志 );parameter S0 2d0;S1 2d1;S2 2d2;S4 …

2023-08-07 LeetCode每日一题(反转字符串)

2023-08-07每日一题 一、题目编号 344. 反转字符串二、题目链接 点击跳转到题目位置 三、题目描述 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间&#xff0c;你必须原地修改输入数组、…

将游戏坐标转化成屏幕鼠标坐标

将游戏坐标转化成屏幕鼠标坐标 思路说明&#xff1a;转化其实是取得两点的相对位置&#xff0c;例如将游戏人物移动到另外一个位置&#xff08;游戏人物初始位置坐标到目的位置坐标&#xff09;&#xff0c;鼠标需要移动到屏幕的某个位置。算出游戏的移动距离&#xff0c;游戏…

SpringBoot3文件管理

标签&#xff1a;上传.下载.Excel.导入.导出&#xff1b; 一、简介 在项目中&#xff0c;文件管理是常见的复杂功能&#xff1b; 首先文件的类型比较多样&#xff0c;处理起来比较复杂&#xff0c;其次文件涉及大量的IO操作&#xff0c;容易引发内存溢出&#xff1b; 不同的…

linux软件安装篇

文章目录 linux软件安装篇配置yum源访问nginx服务页面如何运行一个淘宝网在你的机器上修改nginx的首页 linux软件安装篇 linux是纯黑屏的 学习使用yum工具&#xff0c;安装应用程序 阿里云的yum仓库&#xff0c;https://developer.aliyun.com/mirror/ 阿里云非常丰富且强大…

redis的配置和使用、redis的数据结构以及缓存遇见的常见问题

目录 1.缓存 2.redis不仅仅可以做缓存&#xff0c;只不过说他的大部分场景&#xff0c;是做缓存。本地缓存重启后缓存里的东西就没有了&#xff0c;但是redis有。 3.redis有几个特性:查询快&#xff0c;但是是放到内存里的〈断电或者重启&#xff0c;数据就丢了)&#xff0c…

Vue组件化开发思想;Vue的全局组件;Vue的局部组件;Vue的开发模式和解析;Vue CLI安装和使用;Vue项目的创建方式–Vite

目录 1_Vue组件化开发思想1.1_认识组件化开发1.2_Vue的组件化1.3_注册组件的方式 2_Vue的全局组件3_Vue的局部组件4_Vue的开发模式和解析4.1_Vue的开发模式4.2_单文件的特点4.3_如何支持SFC4.4_VSCode对SFC文件的支持 5_Vue CLI安装和使用5.1_Vue CLI脚手架5.2_Vue CLI 安装和使…

基于react-native的简单消息确认框showModel

基于react-native的简单消息确认框showModel 效果示例图组件代码ShowModel/index.jsx使用案例device.js安装线性渐变色 效果示例图 组件代码ShowModel/index.jsx import React, {forwardRef, useImperativeHandle, useState} from react; import {View,Text,Modal,TouchableOp…

整合封装服务器模块设计实现

服务器模块&#xff0c;是对当前所实现的所有模块的⼀个整合&#xff0c;并进⾏服务器搭建的⼀个模块&#xff0c;最终封装实现出⼀个gobang_server的服务器模块类&#xff0c;向外提供搭建五⼦棋对战服务器的接⼝。通过实例化的对象可以简便的完成服务器的搭建。 服务器框架 …

DNS、ARP

目录 DNS以及它的用途 DNS的解析方式 DNS的查询方式 DNS使用TCP/UDP DNS劫持 常见的DNS劫持现象 DNS劫持与HTTP劫持的不同 处理DNS劫持 DNS缓存 DNS实现负载均衡 ARP以及他的工作原理 DNS以及它的用途 DNS是域名解析服务器&#xff0c;用来将域名解析成IP。DNS工作在…

金九银十面试题之《JUC》

&#x1f42e;&#x1f42e;&#x1f42e; 辛苦牛&#xff0c;掌握主流技术栈&#xff0c;包括前端后端&#xff0c;已经7年时间&#xff0c;曾在税务机关从事开发工作&#xff0c;目前在国企任职。希望通过自己的不断分享&#xff0c;可以帮助各位想或者已经走在这条路上的朋友…

Linux | Ubuntu18.04安装RTX 4060显卡驱动完整教程

文章目录 概述一、定义介绍二、操作教程(一)、前期准备1.进入终端界面2.关闭界面显示器3.禁用其他显卡驱动4.卸载残余显卡驱动5.下载驱动(二)、安装驱动1.给驱动程序赋予权限2.安装驱动3.检查结果(三)、后续问题1.黑屏问题概述 本节详细介绍了如何在ubuntu18系统安装4060显卡的…

pnpm的高级使用

我整理了一些pnpm的高级使用&#xff1a; 并行安装&#xff1a;pnpm通过并行安装依赖项来提高安装速度。默认情况下&#xff0c;它会使用计算机的最大线程数来并行安装依赖项。你也可以使用--recursive选项来并行安装所有子项目的依赖项。 冻结依赖&#xff1a;pnpm支持将依赖…

06微服务间的通信方式

一句话导读 微服务设计的一个挑战就是服务间的通信问题&#xff0c;服务间通信理论上可以归结为进程间通信&#xff0c;进程可以是同一个机器上的&#xff0c;也可以是不同机器的。服务可以使用同步请求响应机制通信&#xff0c;也可以使用异步的基于消息中间件间的通信机制。同…

【云原生|Kubernetes】14-DaemonSet资源控制器详解

【云原生|Kubernetes】14-DaemonSet资源控制器详解 文章目录 【云原生|Kubernetes】14-DaemonSet资源控制器详解简介典型用法DaemonSet语法规则Pod模板Pod 选择算符在选定的节点上运行 Pod DaemonSet的 Pods 是如何被调度的污点和容忍度DaemonSet更新和回滚DaemonSet更新策略执…