探索搜索算法:从顺序到启发式的多种搜索方法

探索搜索算法:从顺序到启发式的多种搜索方法

搜索算法在计算机科学中起着至关重要的作用,帮助我们在大量数据中查找目标值、解决问题,或者找到最优解。本文将深入介绍不同类型的搜索算法,包括顺序搜索、二分搜索、插值搜索、哈希搜索、深度优先搜索、广度优先搜索、A*搜索以及启发式搜索,每种算法都有相应的Java代码示例。

1. 顺序搜索(Sequential Search)

顺序搜索是一种简单的搜索算法,逐个遍历列表中的元素,直到找到目标值。

代码示例

public class SequentialSearch {public static int sequentialSearch(int[] array, int target) {for (int i = 0; i < array.length; i++) {if (array[i] == target) {return i;}}return -1;}public static void main(String[] args) {int[] array = {3, 6, 8, 10, 15, 21, 25};int target = 15;int index = sequentialSearch(array, target);if (index != -1) {System.out.println("目标值 " + target + " 在索引 " + index + " 处找到。");} else {System.out.println("目标值 " + target + " 未找到。");}}
}

2. 二分搜索(Binary Search)

二分搜索适用于已排序的列表,通过重复地将列表一分为二,并判断目标值在哪一半中,从而快速找到目标值。

代码示例

public class BinarySearch {public static int binarySearch(int[] array, int target) {int left = 0;int right = array.length - 1;while (left <= right) {int mid = left + (right - left) / 2;if (array[mid] == target) {return mid;}if (array[mid] < target) {left = mid + 1;} else {right = mid - 1;}}return -1;}public static void main(String[] args) {int[] array = {3, 6, 8, 10, 15, 21, 25};int target = 15;int index = binarySearch(array, target);if (index != -1) {System.out.println("目标值 " + target + " 在索引 " + index + " 处找到。");} else {System.out.println("目标值 " + target + " 未找到。");}}
}

3. 插值搜索(Interpolation Search)

插值搜索是一种在已排序数组中定位目标值的搜索算法,它根据目标值在范围内的估计位置来决定搜索的方向。

代码示例

public class InterpolationSearch {public static int interpolationSearch(int[] array, int target) {int left = 0;int right = array.length - 1;while (left <= right && target >= array[left] && target <= array[right]) {int pos = left + ((target - array[left]) * (right - left)) / (array[right] - array[left]);if (array[pos] == target) {return pos;}if (array[pos] < target) {left = pos + 1;} else {right = pos - 1;}}return -1;}public static void main(String[] args) {int[] array = {3, 6, 8, 10, 15, 21, 25};int target = 15;int index = interpolationSearch(array, target);if (index != -1) {System.out.println("目标值 " + target + " 在索引 " + index + " 处找到。");} else {System.out.println("目标值 " + target + " 未找到。");}}
}

4. 哈希搜索(Hash Search)

哈希搜索利用哈希表的特性,通过计算目标值的哈希值找到对应的位置,从而快速找到目标值。

代码示例

public class HashSearch {public static int hashSearch(int[] array, int target) {HashMap<Integer, Integer> map = new HashMap<>();for (int i = 0; i < array.length; i++) {map.put(array[i], i);}if (map.containsKey(target)) {return map.get(target);}return -1;}public static void main(String[] args) {int[] array = {3, 6, 8, 10, 15, 21, 25};int target = 15;int index = hashSearch(array, target);if (index != -1) {System.out.println("目标值 " + target + " 在索引 " + index + " 处找到。");} else {System.out.println("目标值 " + target + " 未找到。");}}
}

5. 深度优先搜索(DFS)

深度优先搜索是一种遍历图或树的算法,它从起始节点开始,沿着一条路径尽可能深入,直到无法继续为止,然后回退并尝试其他路径。

代码示例

import java.util.ArrayList;
import java.util.List;public class DepthFirstSearch {static class Graph {private int vertices;private List<List<Integer>> adjacencyList;Graph(int vertices) {this.vertices = vertices;adjacencyList = new ArrayList<>(vertices);for (int i = 0; i < vertices; i++) {adjacencyList.add(new ArrayList<>());}}void addEdge(int source, int destination) {adjacencyList.get(source).add(destination);}void DFS(int startVertex) {boolean[] visited = new boolean[vertices];DFSRecursive(startVertex, visited);}void DFSRecursive(int vertex, boolean[] visited) {visited[vertex] = true;System.out.print(vertex + " ");List<Integer> neighbors = adjacencyList.get(vertex);for (int neighbor : neighbors) {if (!visited[neighbor]) {DFSRecursive(neighbor, visited);}}}}public static void main(String[] args) {Graph graph = new Graph(5);graph.addEdge(0, 1);graph.addEdge(0, 2);graph.addEdge(1, 3);graph.addEdge(2, 4);System.out.println("深度优先搜索结果:");graph.DFS(0);}
}

6. 广度优先搜索(BFS)

广度优先搜索也是一种遍历图或树的算法,它从起始节点开始,逐层扩展,先访问距离起始节点近的节点。

代码示例

import java.util.LinkedList;
import java.util.Queue;public class BreadthFirstSearch {static class Graph {private int vertices;private LinkedList<Integer>[] adjacencyList;Graph(int vertices) {this.vertices = vertices;adjacencyList = new LinkedList[vertices];for (int i = 0; i < vertices; i++) {adjacencyList[i] = new LinkedList<>();}}void addEdge(int source, int destination) {adjacencyList[source].add(destination);}void BFS(int startVertex) {boolean[] visited = new boolean[vertices];Queue<Integer> queue = new LinkedList<>();visited[startVertex] = true;queue.offer(startVertex);while (!queue.isEmpty()) {int vertex = queue.poll();System.out.print(vertex + " ");for (int neighbor : adjacencyList[vertex]) {if (!visited[neighbor]) {visited[neighbor] = true;queue.offer(neighbor);}}}}}public static void main(String[] args) {Graph graph = new Graph(5);graph.addEdge(0, 1);graph.addEdge(0, 2);graph.addEdge(1, 3);graph.addEdge(2, 4);System.out.println("广度优先搜索结果:");graph.BFS(0);}
}

7. A*搜索算法

A*搜索算法是一种启发式搜索算法,用于在图中找到最短路径。它同时考虑路径的代价和启发式估计值,以找到一个较优的路径。

代码示例

import java.util.*;public class AStarSearch {static class Node implements Comparable<Node> {int vertex;int distance;int heuristic;Node(int vertex, int distance, int heuristic) {this.vertex = vertex;this.distance = distance;this.heuristic = heuristic;}@Overridepublic int compareTo(Node other) {return Integer.compare(distance + heuristic, other.distance + other.heuristic);}}static class Graph {private int vertices;private List<List<Node>> adjacencyList;Graph(int vertices) {this.vertices = vertices;adjacencyList = new ArrayList<>(vertices);for (int i = 0; i < vertices; i++) {adjacencyList.add(new ArrayList<>());}}void addEdge(int source, int destination, int weight) {adjacencyList.get(source).add(new Node(destination, weight, 0));}int AStar(int startVertex, int goalVertex) {PriorityQueue<Node> priorityQueue = new PriorityQueue<>();int[] distances = new int[vertices];Arrays.fill(distances, Integer.MAX_VALUE);distances[startVertex] = 0;priorityQueue.offer(new Node(startVertex, 0, heuristic(startVertex, goalVertex)));while (!priorityQueue.isEmpty()) {Node current = priorityQueue.poll();if (current.vertex == goalVertex) {return current.distance;}for (Node neighbor : adjacencyList.get(current.vertex)) {int tentativeDistance = distances[current.vertex] + neighbor.distance;if (tentativeDistance < distances[neighbor.vertex]) {distances[neighbor.vertex] = tentativeDistance;priorityQueue.offer(new Node(neighbor.vertex, tentativeDistance, heuristic(neighbor.vertex, goalVertex)));}}}return -1; // No path found}int heuristic(int currentVertex, int goalVertex) {// Replace with appropriate heuristic functionreturn 0;}}public static void main(String[] args) {Graph graph = new Graph(5);graph.addEdge(0, 1, 4);graph.addEdge(0, 2, 1);graph.addEdge(1, 3, 1);graph.addEdge(2, 3, 5);graph.addEdge(2, 4, 3);graph.addEdge(3, 4, 2);int startVertex = 0;int goalVertex = 4;int distance = graph.AStar(startVertex, goalVertex);if (distance != -1) {System.out.println("A*搜索结果:从节点 " + startVertex + " 到节点 " + goalVertex + " 的最短路径距离为 " + distance);} else {System.out.println("无法找到从节点 " + startVertex + " 到节点 " + goalVertex + " 的路径。");}}
}

8. 启发式搜索算法

启发式搜索算法通过启发式函数(heuristic function)来指导搜索方向,以期望更快地找到目标状态或解。

代码示例(以A*搜索为例):

// 请参考前面的A*搜索算法示例

总结

搜索算法在计算机科学和人工智能

领域中具有重要作用。本文深入介绍了不同类型的搜索算法,包括顺序搜索、二分搜索、插值搜索、哈希搜索、深度优先搜索、广度优先搜索、A*搜索以及启发式搜索。通过理解这些算法的工作原理和示例代码,您可以更好地应用它们来解决各种问题。

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

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

相关文章

Gradio、Streamlit和Dash应用场景和功能比较

文章目录 应用比较GradioStreamlitplotly dash应用比较 gradiostreamlitdash主要使用场景可交互的小demo工作流、Dashboarddashboard、生产环境的复杂演示应用上手难度简单简单中等组件丰富度低中高Jupyter Notebook支持是否是是否完全开源是是部分企业级功能未开源GitHub star…

从0到1学会Git(第一部分):Git的下载和初始化配置

1.Git是什么: 首先我们看一下百度百科的介绍:Git&#xff08;读音为/gɪt/&#xff09;是一个开源的分布式版本控制系统&#xff0c;可以有效、高速地处理从很小到非常大的项目版本管理。 也是Linus Torvalds为了帮助管理Linux内核开发而开发的一个开放源码的版本控制软件。 …

Azure - AzCopy学习

使用 AzCopy 将本地数据迁移到云存储空间 azcopy login 创建存储账号 ./azcopy login --tenant-id 40242385-c249-4746-95dc-4a0b64d49dc5这里的—tenant-id 在下面的地方查看&#xff1a;目录 ID&#xff1b;需要拥有Storage Blob Data Owner 的权限账号下可能会有很多目录&am…

nginx生成自定义证书

1、创建key文件夹 [rootlocalhost centos]# mkdir key 进入key文件夹 [rootlocalhost centos]# cd key/ 2、生成私钥文件 [rootlocalhost key]# openssl genrsa -des3 -out ssl.key 4096 输入这个key文件的密码。不推荐输入&#xff0c;因为以后要给nginx使用。每次reload ngin…

帆软报表系统SSRF

有子曰&#xff1a;“信近于义&#xff0c;言可复也。恭近礼&#xff0c;远耻辱也。因不失其亲&#xff0c;亦可宗也。” SSRF 构造payload&#xff0c;访问漏洞url&#xff1a; /ReportServer?opresource&resourcehttp://x.x.x漏洞证明&#xff1a; 文笔生疏&#xf…

软考A计划-系统集成项目管理工程师-法律法规-下

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 &#x1f449;关于作者 专注于Android/Unity和各种游…

React钩子函数之useRef的基本使用

React钩子函数中的useRef是一个非常有用的工具&#xff0c;它可以用来获取DOM元素或者保存一些变量。在这篇文章中&#xff0c;我们将会讨论useRef的基本使用。 首先&#xff0c;我们需要知道useRef是如何工作的。它返回一个可变的ref对象&#xff0c;这个对象可以在组件的整个…

AWS EC2 docker-compose部署MongoDB4.2

环境准备 安装docker 参考EC2官方文档&#xff1a;创建容器镜像以在 Amazon ECS 上使用 - Amazon Elastic Container Service sudo yum update -y sudo amazon-linux-extras install docker sudo usermod -a -G docker ec2-user sudo systemctl enable docker sudo systemct…

算法通关村第十五关——从10亿数字中寻找最小的100万个数字

题目要求&#xff1a;设计一个算法&#xff0c;给定一个10亿个数字&#xff0c;找出最小的100万的数字。假定计算机内存足以容纳全部10亿个数字。 本题有三种常用的方法&#xff0c;一种是先排序所有元素&#xff0c;然后取出前100万个数&#xff0c;该方法的时间复杂度为O(nl…

数学建模(四)整数规划—匈牙利算法

目录 一、0-1型整数规划问题 1.1 案例 1.2 指派问题的标准形式 2.2 非标准形式的指派问题 二、指派问题的匈牙利解法 2.1 匈牙利解法的一般步骤 2.2 匈牙利解法的实例 2.3 代码实现 一、0-1型整数规划问题 1.1 案例 投资问题&#xff1a; 有600万元投资5个项目&…

mac 10.13.6安装后开发准备工作

git下载安装 xcode旧版安装搜索 brew国内源安装 brew国内源安装地址2 brew更换源 SwitchHosts github hosts nfts磁盘读写工具 更新ssl证书 证书下载 然后备份一下系统原来的pem文件 cp /etc/ssl/cert.pem /etc/ssl/cert.bak.pem 之后将新下载的pem文件&#xff0c;拷贝到/etc…

【笔记】经典Integer对象赋值128问题

Integer经典面试问题&#xff1a;两个Integer对象都赋值为128&#xff0c;这两个对象比较是否相同&#xff1f;为什么&#xff1f; 回答这个问题&#xff0c;首先我们要知道&#xff0c;在Java中&#xff0c;当你写Integer a 1; 实际上是调用了Java的自动装箱功能。这会将整数…

Redis7安装

1. 使用什么系统安装redis 由于企业里面做Redis开发&#xff0c;99%都是Linux版的运用和安装&#xff0c;几乎不会涉及到Windows版&#xff0c;上一步的讲解只是为了知识的完整性&#xff0c;Windows版不作为重点&#xff0c;同学可以下去自己玩&#xff0c;企业实战就认一个版…

几个nlp的小任务(抽取式问答)

几个nlp的小任务(抽取式问答) 安装库抽取式问答介绍、SQuAD数据集初始化参数加载、导入数据集查看数据集示例加载tokenizer对长文本处理的演示对答案的位置进行验证整合刚才的步骤对数据集中的数据进行预处理加载微调模型设置args 参数使用数据清洗设置训练函数,开始训练安装…

从零学算法 (剑指 Offer 13)

地上有一个m行n列的方格&#xff0c;从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动&#xff0c;它每次可以向左、右、上、下移动一格&#xff08;不能移动到方格外&#xff09;&#xff0c;也不能进入行坐标和列坐标的数位之和大于k的格子。例如&am…

STM32开发 | 移远4G-Cat.1模组EC200N-CN开发

一、硬件说明 1、引脚分配图 文章来源地址https://www.yii666.com/blog/326636.html文章来源地址:https://www.yii666.com/blog/326636.html 2、常用引脚说明 模块输入电源 引脚名描述VBAT_BB模块基带电源&#xff08;Vnom 3.8 V&#xff09;VBAT_RF模块射频电源&#xff0…

Linux操作系统--常用指令(帮助命令)

(1).概述 在日常生活中,我们遇到不认识的字怎么办?小学的时候,我们知道我们可以查字典来认识这一个字,那么如果是Linux操作系统中遇到不认识的指令,该怎么办呢?同样,linux提供了帮助命令以便于我们更好的认识这一个指令。下面我们一起来看一下Linux操作系统提供给我们的…

软件测试技术分享丨使用Postman搞定各种接口token实战

现在许多项目都使用jwt来实现用户登录和数据权限&#xff0c;校验过用户的用户名和密码后&#xff0c;会向用户响应一段经过加密的token&#xff0c;在这段token中可能储存了数据权限等&#xff0c;在后期的访问中&#xff0c;需要携带这段token&#xff0c;后台解析这段token才…

设计模式之工厂方法模式

目录 工厂方法模式 简介 优缺点 结构 使用场景 实现 1.抽象产品 2.具体产品 3.抽象工厂 4.具体工厂 5.调用 总结 抽象工厂模式 简介 结构 实现 区别 工厂方法模式 简介 提供一个用于创建对象的接口(工厂接口)&#xff0c;让其实现类(工厂实现类)决定实例化哪…

Redis内存策略

文章目录 Redis内存策略过期策略DB结构惰性删除周期删除 淘汰策略 Redis内存策略 Redis是基于内存存储&#xff0c;所以其性能很强。但单节点的Redis内存不宜过大&#xff0c;否则会影响持久化或主从同步性能。 可以手动修改配置文件来设置Redis的最大内存 # 格式&#xff1…