二分查找(折半查找)算法
一、二分查找算法基本思想
二分查找(Binary Search),又称折半查找,是一种在有序数组(前提条件)中查找某一特定元素的查找算法。
查找过程从数组的中间元素开始,若中间元素正好是要查找的元素,则查找过程结束;若某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且和开始一样从中间元素开始比较。若在某一步骤时数组为空,则代表找不到。
二、二分查找算法图解
在二分查找算法中,查找37只需要三步;在线性查找算法中,查找37需要11步。
三、代码实现
1、非递归方式
package Search;import java.util.Arrays;
import java.util.Scanner;public class BinarySearch {public static int binarysearch(int[] arr,int value) {int low=0;//指针low表示待查元素所在范围的下界,下界索引从0开始int high=arr.length-1;//指针high表示待查元素所在范围的上界while(low<=high) {int mid=(low+high)/2;//指针mid表示中间位置,且是向下取整if(arr[mid]==value) {//若中间位置值等于我们所需要查找值,即返回中间值return mid;}if(arr[mid]<value) {//若中间位置值小于我们所需查找值,则在后半段中查找,即将下界值变为mid+1,上界值不变low=mid+1;}if(arr[mid]>value) {//若中间位置值大于我们所需查找值,则在前半段中查找,即将上界值变为mid-1,下界值不变high=mid-1;}}return -1;//若查找不到我们所需要值,即返回-1}public static void main(String[] args) {int[] arr= {31,17,5,47,11,33,3,19,13,59,1,43,41,37,7,53,29};Arrays.sort(arr);//采用二分查找时,需要对该数组进行排序Scanner sc=new Scanner(System.in);System.out.println("请输入查找元素:");int value=sc.nextInt();System.out.printf("查找元素 %d 的位置是 %d ",value,binarysearch(arr,value));}
}
运行结果:
请输入查找元素:
43
查找元素 43 的位置是 13
2、递归方式
package Search;import java.util.Arrays;
import java.util.Scanner;public class BinarySearch {public static int binarysearch(int[] arr,int value,int low,int high) {while(low<=high) {int mid=(low+high)/2;//指针mid表示中间位置,且是向下取整if(arr[mid]==value) {//若中间位置值等于我们所需要查找值,即返回中间值return mid;}if(arr[mid]<value) {//若中间位置值小于我们所需查找值,则向右递归且将下界值变为mid+1return binarysearch(arr,value,mid+1,high);}if(arr[mid]>value) {//若中间位置值大于我们所需查找值,则向左递归将上界值变为mid-1return binarysearch(arr,value,low,mid-1);}}return -1;}public static void main(String[] args) {int[] arr= {31,17,5,47,11,33,3,19,13,59,1,43,41,37,7,53,29};Arrays.sort(arr);//采用二分查找时,需要对该数组进行排序Scanner sc=new Scanner(System.in);System.out.println("请输入查找元素:");int value=sc.nextInt();System.out.printf("查找元素 %d 的位置是 %d ",value,binarysearch(arr,value,0,arr.length-1));}
}
运行结果:
请输入查找元素:
37
查找元素 37 的位置是 11
四、二分查找算法改进
当一个有序数组中,我们所需要查找的元素有多个时,利用上面程序显然只能返回第一个元素的位置下标,无法返回所有元素的位置下标。我们可以利用ArrayList来存放所有相同元素位置下标,当我们知道mid索引值时,不要马上返回;应该向mid索引值的左边继续扫描和向mid索引值的右边继续扫描,将所有满足条件的元素位置下标放入ArrayList中。
package Search;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;public class BinarySearch {public static List<Integer> binarysearch(int[] arr,int value,int low,int high) {while(low<=high) {int mid=(low+high)/2;//指针mid表示中间位置,且是向下取整if(arr[mid]==value) {List<Integer> list=new ArrayList<>();int temp=mid-1;//向mid索引值的左边扫描while(true) {if(temp<0||arr[temp]!=value) {break;}list.add(temp);//退出while循环则符合条件加入list中temp--;//temp继续向左移}list.add(mid);//中间值要加入list中temp=mid+1;//向mid索引值的右边扫描while(true) {if(temp>arr.length-1||arr[temp]!=value) {break;}list.add(temp);//退出while循环则符合条件加入list中temp++;//temp继续向右移}return list;}if(arr[mid]<value) {//若中间位置值小于我们所需查找值,则向右递归且将下界值变为mid+1return binarysearch(arr,value,mid+1,high);}if(arr[mid]>value) {//若中间位置值大于我们所需查找值,则向左递归将上界值变为mid-1return binarysearch(arr,value,low,mid-1);}}return null;//没有找到则返回null}public static void main(String[] args) {int[] arr= {2,6,7,8,4,3,5,1,7,0,3,4,5,9,2,7,7,7};Arrays.sort(arr);//采用二分查找时,需要对该数组进行排序Scanner sc=new Scanner(System.in);System.out.println("请输入查找元素:");int value=sc.nextInt();List<Integer> list = binarysearch(arr,value,0,arr.length-1);System.out.printf("查找元素 %d 的位置是:",value);System.out.println(list);}
}
运行结果:
请输入查找元素:
7
查找元素 7 的位置是:[12, 11, 13, 14, 15]
二分查找(折半查找)算法相关推荐
- 二分查找/折半查找算法
二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.首先,假设表中元素是按升序排列,将表 ...
- 顺序表查找+折半查找(二级)
我们讲了各种数据 结构之后,比如讲了线性表了,讲了栈和队列,讲了树和二叉树,讲了图之后呢,我们最后还有两个专题,一个叫查找,一个叫排序,我们先看看查找,查找包括哪些内容啊,第一个线性表的查找,数组或者 ...
- c语言折半查找输出坐标,数据结构(C语言版)——有序表查找(折半查找)(代码版)...
数据结构(C语言版)--有序表查找(折半查找)(代码版) 数据结构(C语言版)--有序表查找(折半查找)(代码版) #include #include #define ERROR 0 #define ...
- Python二分查找/折半查找算法详解--(面试常考)
https://blog.csdn.net/hanhanwanghaha宝藏女孩 欢迎您的关注! 欢迎关注微信公众号:宝藏女孩的成长日记 如有转载,请注明出处(如不注明,盗者必究) 二分查找也称折 ...
- swift版 二分查找 (折半查找)
二分查找作为一种常见的查找方法,将原本是线性时间提升到了对数时间范围之内,大大缩短了搜索时间,但它有一个前提,就是必须在有序数据中进行查找.废话少说,直接上代码,可复制粘贴直接出结果! import ...
- 顺序查找 折半查找 二叉排序树
1.顺序查找,折半查找,二叉排序树操作定义 SeqSearch.h #include<stdio.h> #define ARRAYLEN 8int source[]={69, 65, 90 ...
- C语言数组查找(线性查找 折半查找)
线性查找 #include <stdio.h> #include <math.h>void find_nine(int numbers[]) {int i;for(i = 0; ...
- php折半查找算法,二分查找 [折半查找] 算法 PHP 版
查找表:就是同一类型的数据元素构成的数据集合 有静态表和动态表 本文实现PHP版的二分查找算法[本算法仅用于顺序存储的查找表] /** * Created by PhpStorm. * User: 1 ...
- DS查找—折半查找求阶乘函数后K个零
题目描述 f(x) 是 x! 末尾是 0 的数量,给定 K,找出多少个非负整数 x ,能满足 f(x) = K . (x! = 1 * 2 * 3 * - * x,且 0! = 1 ) 例如, f(3 ...
- c语言实验报告 折半查找法,C语言数组之冒泡排序+折半查找法(二分查找)
冒泡排序算法 将相邻的元素进行两两比较,大的向后"冒", 小的向前"赶". 口诀: N个数字来排队,两两比较小靠前 外层循环N-1(控制需要比较的轮数). 内层 ...
最新文章
- brightness temperature
- 最大子段和(动态规划及分治法)
- 排除问题的时候不要随意修改系统筛选数据的逻辑
- Python学习者可能存在的几个问题,你遇到过吗?
- css圆角box(网上流行用b标签)
- 深入理解分布式消息队列
- Leecode22. 括号生成——Leecode大厂热题100道系列
- 值得收藏!268条PCB layout设计规范
- mysql常见数据库设计_常见数据库设计
- Oracle相关练习
- 计算机算法设计与分析 循环赛日程表
- 企业级 SpringBoot 教程 (十四)在springboot中用redis实现消息队列
- Redis进阶之redis的生命周期
- 【项目管理】项目启动阶段 -- 制定项目章程
- MacBook Pro 开机密码忘记的解决办法
- python基础课程讲解基本语法常见运算符以及结构语句
- verilog语言中的@什么意思 verilog语言中的@什么意思
- import java.sql.*;问题:The package java.sql is not accessible
- 【图像去噪】基于非局部均值(NLM)滤波图像去噪含Matlab源码
- 【Moasure魔尺】它是如何工作的?
热门文章
- 解决:Command line is too long. Shorten command line for xxx or also for Application default configurat
- 【图像融合】基于matlab稀疏表示多光谱图像融合【含Matlab源码 1301期】
- 【SpringBoot】Command line is too long.Shorten command line for XXXApplication
- 手把手教你实现在Monaco Editor中使用VSCode主题
- 3d渲染时显示计算机渲染过程,【技巧分享】如何解决3d渲染时出现错误
- Nginx(七)防盗链
- python中turtle画老虎_通过Turtle库在Python中绘制一个鼠年福鼠
- 【VR】虚拟现实相关硬件设备
- 【爬虫】抓取京东商品列表具体商品的各种评论数量-2019年6月可用
- 高光谱图像分类python语言编写 改进lstm算法