查找算法及应用

查找算法及应用

常用查找算法包括顺序/线性查找、二分/折半查找、插值查找、斐波那契查找。

  1. 线性查找

    逐一比对,发现有相同值返回即可。

  2. 二分查找

    前提是数组有序。如果数据是连续的情况下可以使用插值查找。

  3. 插值查找

    插值查找算法类似二分查找,不同的是插值查找每次从自适应中间位置处开始查找。数据比较连续情况下实用。将折半查找中的求mid索引的公式改进,low表示左边索引left,high表示右边索引right,key表示查找的值。
    m i d = l o w + h i g h 2 = l o w + 1 2 ( l o w + h i g h ) mid = \frac{low+high}{2} = low + \frac{1}{2}(low + high) mid=2low+high=low+21(low+high)

    m i d = l o w + k e y − a [ l o w ] a [ h i g h ] − a [ l o w ] ( h i g h − l o w ) mid = low + \frac{key - a[low]}{a[high] - a[low]}(high - low) mid=low+a[high]a[low]keya[low](highlow)

  4. 斐波那契查找

    黄金分割点是指把一条线段分成两段,使其中一部分与全长之比等于另一部分与这一部分之比,取其前三位数字的近似值是0.618。斐波那契数列的两个相邻数的比例,无线接近黄金分割值0.618。斐波那契查找原理是改变中间节点mid的位置,mid=low+F(k-1)-1,其中F代表斐波那契数列。

/*** 抽象父类*/
public abstract class SearchParent {protected static int[] arr = {1, 8, 10, 89, 1000, 1000, 1000, 1234};//在数组中查找指定值的位置abstract int search(int[] arr, int val);
}
/*** 线性查找*/
public class SimpleSearch extends SearchParent {public static void main(String[] args) {System.out.println("89的下标是:" + new SimpleSearch().search(arr, 89));}@Overrideint search(int[] arr, int val) {for (int i=0;i<arr.length;i++){if (val == arr[i]) {return i;}}    return -1;}    
}
import java.util.ArrayList;
import java.util.List;/*** 折半查找*/
public class BinarySearch extends SearchParent {public static void main(String[] args) {integerOverflow();System.out.println("The index of 1000 is " + new BinarySearch().search(arr, 1000));}@Overrideint search(int[] arr, int val) {int left = 0;int right = arr.length - 1;return binarySearch(arr, left, right, val);}//只能查找到第一个匹配的值private static int binarySearch(int[] arr, int left, int right, int val){int mid = (left + right)/2;int tmp = arr[mid];if(left > right){return -1;}if(val > tmp){return binarySearch(arr, mid+1, right, val);}else if(val < tmp){return binarySearch(arr, left, mid-1, val);}else{return mid;}}//折半查找非递归方式实现private static int binarySearch(int[] arr, int val){int left = 0;int right = arr.length - 1;while(left <= right){int mid = (left + right)/2;if(arr[mid] > val){right = mid - 1;}else if(arr[mid] < val){left = mid + 1;}else{return mid;}}return -1;}//查找所有符和的值private static List<Integer> binary2Search(int[] arr, int left, int right, int val){int mid = (left + right)/2;int tmp = arr[mid];if(left > right){return null;}if(val > tmp){return binary2Search(arr, mid + 1, right, val);}else if(val < tmp){return binary2Search(arr, left, mid-1, val);}else{List<Integer> result = new ArrayList<>(arr.length);int temp = mid-1;while(temp >= 0 && arr[temp] == val) {result.add(temp);temp--;}result.add(mid);temp = mid + 1;while(temp <= arr.length-1 && arr[temp] == val){result.add(temp);temp++;}return result;}}//获取中间索引可能会出现整数溢出private static void integerOverflow(){int l = 0;int r = Integer.MAX_VALUE - 1;int m = (l+r)/2;System.out.println(m);l = m + 1;//m = (l+r)/2; 会导致整数溢出//m = l + (r-l)/2; 除法效率较差m = (l+r)>>>1;System.out.println(m);}
}
/*** 插值查找*/
public class InsertValSearch extends SearchParent {public static void main(String[] args) {System.out.println("1000的下标是:" + new InsertValSearch().search(arr, 1000));}@Overrideint search(int[] arr, int val) {int left = 0;int right = arr.length - 1;return insertSearchValue(arr, left, right, val);}private int insertSearchValue(int[] arr, int left, int right, int val) {if(left > right || val < arr[0] || val > arr[arr.length-1]){return -1;}int mid = left + (right-left)*(val-arr[left])/(arr[right]-arr[left]);int temp = arr[mid];if(val > temp){return insertSearchValue(arr, mid+1, right, val);}else if(val < temp){return insertSearchValue(arr, left, mid+1, val);}else{return mid;}}
}
import java.util.Arrays;/*** 斐波那契查找*/
public class FibonacciSearch extends SearchParent {private static final int MAXSIZE = 20;public static void main(String[] args) {System.out.println(new FibonacciSearch().search(arr, 1000));}//生成斐波那契数组private int[] fib(){int[] f = new int[MAXSIZE];f[0] = 1;f[1] = 1;for(int i=2;i<MAXSIZE;i++){f[i] = f[i-2] + f[i-2];}return f;}@Overrideint search(int[] arr, int val) {int low = 0;int high = arr.length - 1;int k = 0; //表示斐波那契分割值的下标int mid = 0;int[] f = fib(); //获取斐波那契分割数值的下标//找到数组长度对应的斐波那契数列中对应的元素F(n)的值while(high > f[k] - 1){k++;}int[] temp = Arrays.copyOf(arr, f[k]); //F(k)的值可能大于arr的长度,不足部分使用0填充//使用数组的最后一个数填充for(int i=high+1;i<temp.length;i++){temp[i] = arr[high];}while(low <= high){mid = low + f[k-1] - 1;if(val < temp[mid]){//全部元素=前面元素+后面元素,f[k]=f[k-1]+f[k-2]//因为前面有f[k-1]个元素,所以可以继续拆分f[k-1]=f[k-2]+f[k-3]high = mid - 1;k-=1;}else if(val > temp[mid]){low = mid + 1;//因为后面有f[k-2]个元素,所以可以继续拆分k-=2;}else{if(mid <= high){ //如果是原查找表中的元素return mid;}else{return high; //如果是填充值}}}return -1;}
}

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

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

相关文章

快速学习GO语言总结

备注&#xff1a;本博客将自己初步学习GO的总结进行分享&#xff0c;希望大家通过本博客可以在短时间内快速掌握GO的基本程序编码能力&#xff0c;如有错误请留言指正&#xff0c;谢谢&#xff01; 一、初步了解Go语言 &#xff08;一&#xff09;Go语言诞生的主要问题和目标…

8.3 【C语言】通过指针引用数组

8.3.1 数组元素的指针 所谓数组元素的指针就是数组元素的地址。 可以用一个指针变量指向一个数组元素。例如&#xff1a; int a[10]{1,3,5,7,9,11,13,15,17,19}&#xff1b; int *p; p&a[0]&#xff1b; 引用数组元素可以用下标法&#xff0c;也可以用指针法&#xf…

iOS17 widget Content margin

iOS17小组件有4个新的地方可以放置分别是&#xff1a;Mac桌面、iPad锁屏界面、 iPhone Standby模式、watch的smart stack Transition to content margins iOS17中苹果为widget新增了Content margin, 使widget的内容能够距离边缘有一定的间隙&#xff0c;确保内容显示完整。这…

【WinAPI详解】<CreateWindowEx详解>

函数原型: HWND CreateWindowEx(DWORD dwExStyle, //窗口的扩展风格&#xff08;加强版专有&#xff09;LPCTSTR lpClassName, //已经注册的窗口类名称LPCTSTR lpWindowName,//窗口标题栏的名字DWORD dwStyle, //窗口的基本风格int x, //窗口左上角水平坐标位置int …

学习设计模式之适配器模式,但是宝可梦

前言 作者在准备秋招中&#xff0c;学习设计模式&#xff0c;做点小笔记&#xff0c;用宝可梦为场景举例&#xff0c;有错误欢迎指出。 适配器模式 意图&#xff1a;将一个类的接口转换成客户希望的另一个接口 主要解决&#xff1a;把现有对象放到新环境里&#xff0c;而新…

通过C实现sqlite3操作,(增删改查),导入电子词典

一、插入 #include <stdio.h> #include <sqlite3.h> void do_insert(sqlite3 *db); int main(int argc, const char *argv[]) {//创建并打开一个数据库sqlite3 *db NULL;if(sqlite3_open("./mysql.db",&db) ! SQLITE_OK){fprintf(stderr,"sql…

AUTOSAR配置与实践(配置篇)5.1 BSW的通信功能进阶

传送门 -> AUTOSAR配置与实践总目录 AUTOSAR配置与实践(配置篇)5.1 BSW的通信功能进阶 一、模块和收发流程主要配置项介绍1.1 模块介绍1.2 通知方式相关主要配置项二、收发流程详解2.1 发送流程2.2 发送确认过程2.2.1 发送确认过程(读数据方式:轮询)2.2.2 发送确认过程…

IDEA 如何制作代码补丁?IDEA 生成 patch 和使用 patch

什么是升级补丁&#xff1f; 比如你本地修复的 bug&#xff0c;需要把增量文件发给客户&#xff0c;很多场景下大家都需要手工整理修改的文件&#xff0c;并整理好目录&#xff0c;这个很麻烦。那有没有简单的技巧呢&#xff1f;看看 IDEA 生成 patch 和使用 patch 的使用。 介…

Centos升级openssl

依赖包 安装编译 OpenSSL 所需的包&#xff0c;包括 gcc、make、perl 和 zlib-devel。可以通过运行以下命令完成&#xff1a; yum install -y gcc make perl zlib-devel安装包下载 下载 OpenSSL 1.1.1 的源码包&#xff0c;可以从 OpenSSL 官网下载&#xff08;https://www.op…

一、Kafka概述

目录 1.3 Kafka的基础架构 1.3 Kafka的基础架构 Producer&#xff1a;消息生产者&#xff0c;就是向 Kafka broker 发消息的客户端Consumer&#xff1a;消息消费者&#xff0c;向 Kafka broker 取消息的客户端。Consumer Group&#xff08;CG&#xff09;&#xff1a;消费者组&…

使用pytorch 的Transformer进行中英文翻译训练

下面是一个使用torch.nn.Transformer进行序列到序列&#xff08;Sequence-to-Sequence&#xff09;的机器翻译任务的示例代码&#xff0c;包括数据加载、模型搭建和训练过程。 import torch import torch.nn as nn from torch.nn import Transformer from torch.utils.data im…

PyTorch学习笔记(十六)——利用GPU训练

一、方式一 网络模型、损失函数、数据&#xff08;包括输入、标注&#xff09; 找到以上三种变量&#xff0c;调用它们的.cuda()&#xff0c;再返回即可 if torch.cuda.is_available():mynn mynn.cuda() if torch.cuda.is_available():loss_function loss_function.cuda(…

SpringMVC之@RequestMapping注解

文章目录 前言一、RequestMapping介绍二、详解&#xff08;末尾附源码&#xff0c;自行测试&#xff09;1.RequestMapping注解的位置2.RequestMapping注解的value属性3.RequestMapping注解的method属性4.RequestMapping注解的params属性&#xff08;了解&#xff09;5.RequestM…

华为ENSP网络设备配置实战6(简单的链路聚合)

题目要求 1、创建聚合组&#xff0c;添加端口成员 2、PC1网段为vlan10&#xff0c;PC2网段为vlan20 3、LSW1为核心网关设备&#xff0c;正确配置PC网关 4、PC1与PC2互通 解题过程 1.1、 按照拓扑图&#xff0c;各个设备起名 sys &#xff08;进入系统视图&#xff09; sy…

写一个mysql 正则表达式,每三个img标签图片后面添加<hr>

你可以使用MySQL的REGEXP_REPLACE函数来实现这个需求。下面是一个示例的正则表达式和SQL语句&#xff1a; sql UPDATE your_table SET your_column REGEXP_REPLACE(your_column, (<img[^>]*>){3}, $0<hr>) WHERE your_column REGEXP (<img[^>]*>){3}…

TCP协议报文结构

TCP是什么 TCP&#xff08;传输控制协议&#xff09;是一种面向连接的、可靠的、全双工的传输协议。它使用头部&#xff08;Header&#xff09;和数据&#xff08;Data&#xff09;来组织数据包&#xff0c;确保数据的可靠传输和按序传递。 TCP协议报文结构 下面详细阐述TCP…

FRP内网穿透,配置本地电脑作为服务器

FRP内网穿透&#xff0c;配置本地电脑作为服务器 下载FRP服务端客户端 参考链接&#xff1a; https://www.it235.com/实用工具/内网穿透/pierce.html https://www.cnblogs.com/007sx/p/17469301.html 由于没有公网ip&#xff0c;所以尝试内网穿透将本地电脑作为服务器&#xff…

Servlet+JDBC实战开发书店项目讲解第11讲:管理员用户权限功能

ServletJDBC实战开发书店项目讲解第11讲&#xff1a;管理员用户权限功能 在这一讲中&#xff0c;我们将详细讲解如何实现书店项目中的管理员用户权限功能。下面是每个步骤的详细说明&#xff1a; 步骤一&#xff1a;创建管理员用户表 首先&#xff0c;我们需要在数据库中创建…

【Mariadb高可用MHA】

目录 一、概述 1.概念 2.组成 3.特点 4.工作原理 二、案例介绍 1.192.168.42.3 2.192.168.42.4 3.192.168.42.5 4.192.168.42.6 三、实际构建MHA 1.ssh免密登录 1.1 所有节点配置hosts 1.2 192.168.42.3 1.3 192.168.42.4 1.4 192.168.42.5 1.5 192.168.42.6 …

(二)结构型模式:7、享元模式(Flyweight Pattern)(C++实例)

目录 1、享元模式&#xff08;Flyweight Pattern&#xff09;含义 2、享元模式的UML图学习 3、享元模式的应用场景 4、享元模式的优缺点 5、C实现享元模式的简单实例 1、享元模式&#xff08;Flyweight Pattern&#xff09;含义 享元模式&#xff08;Flyweight&#xff09…