Java实现优先队列式广度优先搜索算法的示例代码

实现优先队列式广度优先搜索(Priority Queue-based BFS)算法需要遵循以下几个步骤:

Step 1:初始化

首先,我们需要初始化一个待访问节点的优先队列priority queue、一个已访问节点的哈希表visited map、以及图的邻接表adjacent list。将源节点加入到priority queue中,并将visited map置为true。

PriorityQueue<Node> pq = new PriorityQueue<>();
Map<Node, Boolean> visited = new HashMap<>();
Map<Node, List<Node>> adj = new HashMap<>();
pq.offer(sourceNode);
visited.put(sourceNode, true);

Step 2:广度优先遍历

接下来,我们可以开始从priority queue中取出最高优先级的节点,检查它是否为目标节点,如果是则直接返回结果;如果不是,则将它的所有邻居节点加入到priority queue,并将它们在visited map中标记为已访问。这个过程就是广度优先遍历的核心算法。

while (!pq.isEmpty()) {
    Node currNode = pq.poll();
    if (currNode == targetNode) {
        return true; // 找到目标节点,直接返回true
    }
    List<Node> neighbors = adj.get(currNode);
    for (Node neighbor : neighbors) {
        if (!visited.containsKey(neighbor)) { // 如果邻居节点没有被访问过
            visited.put(neighbor, true);
            pq.offer(neighbor); // 加入到优先队列中
        }
    }
}

Step 3:构建图的邻接表

最后,我们需要构建图的邻接表,以便进行广度优先遍历。下面是一个简单的例子,展示了如何将节点之间的联系表达为邻接表。

class Node {
    int val;
    List<Node> neighbors;
}
Map<Node, List<Node>> adj = new HashMap<>();
for (Node node : nodeList) {
    adj.putIfAbsent(node, new ArrayList<>());
    for (Node neighbor : node.neighbors) {
        adj.get(node).add(neighbor);
    }
}

示例1

我们可以使用Priority Queue-based BFS算法来解决Kth Smallest Element in a Sorted Matrix这道题目。该题目要求我们在一个二维矩阵中找到第K小的数,可以将该矩阵看做一个有序矩阵。我们可以从矩阵左上角开始,按行向右、按列向下遍历矩阵,并将每个数加入到priority queue中。这样,可以保证队列中的数总是有序的,可以快速找到第K小的数。

public int kthSmallest(int[][] matrix, int k) {
    PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> b - a); // 大根堆
    for (int i = 0; i < matrix.length; i++) {
        for (int j = 0; j < matrix[i].length; j++) {
            pq.offer(matrix[i][j]);
            if (pq.size() > k) {
                pq.poll(); // 只保留前K小的数
            }
        }
    }
    return pq.peek();
}

示例2

我们可以使用Priority Queue-based BFS算法来解决Dijkstra algorithm这道题目。该题目要求我们求解从源节点到目标节点的最短路径,可以将每个节点看做图中的一个顶点,将它们之间的距离看做权重。我们可以使用Priority Queue-based BFS算法来查找从源节点到目标节点的最短路径,过程中使用visited map来记录已访问的节点,通过邻接表来存储节点之间的距离。

public int dijkstra(int[][] edges, int sourceNode, int targetNode) {
    PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[1] - b[1]); // 小根堆
    Map<Integer, List<int[]>> adj = new HashMap<>();
    Map<Integer, Integer> dist = new HashMap<>();
    pq.offer(new int[]{sourceNode, 0});
    dist.put(sourceNode, 0);
    for (int[] edge : edges) {
        adj.putIfAbsent(edge[0], new ArrayList<>());
        adj.get(edge[0]).add(new int[]{edge[1], edge[2]});
    }
    while (!pq.isEmpty()) {
        int[] currNode = pq.poll();
        if (currNode[0] == targetNode) {
            return dist.get(currNode[0]); // 找到目标节点,返回最短距离
        }
        if (!adj.containsKey(currNode[0])) {
            continue;
        }
        for (int[] neighbor : adj.get(currNode[0])) {
            int newDist = currNode[1] + neighbor[1];
            if (!dist.containsKey(neighbor[0]) || newDist < dist.get(neighbor[0])) {
                dist.put(neighbor[0], newDist);
                pq.offer(new int[]{neighbor[0], newDist});
            }
        }
    }
    return -1;
}

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java实现优先队列式广度优先搜索算法的示例代码 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • JSP安全开发之XSS漏洞详解

    JSP安全开发之XSS漏洞详解 跨站脚本(Cross Site Scripting,简称 XSS)攻击是指攻击者往Web页面里插入恶意的Script代码,当用户浏览该页面时,嵌入其中Web里面的Script代码会被执行,从而达到攻击者的目的,如盗取用户的Cookie、登录信息等。 XSS攻击的类型 反射型XSS攻击 反射型 XSS 攻击是指攻击者要求用户点击…

    Java 2023年6月15日
    00
  • SpringBoot项目将mybatis升级为mybatis-plus的方法

    下面是详细讲解 SpringBoot 项目将 Mybatis 升级为 Mybatis-Plus 的方法: 一、前置准备 1. 项目环境 SpringBoot版本:2.5.1 Mybatis版本:3.5.4 2. 引入依赖 在项目 pom.xml 中的 dependencies 中,加入以下依赖: <!– Mybatis-plus –> &lt…

    Java 2023年5月20日
    00
  • Java基础之面向对象机制(多态、继承)底层实现

    Java基础之面向对象机制(多态、继承)底层实现 Java作为一种面向对象的语言,通过多态和继承两种机制来实现面向对象的特性。本文将从底层角度分别探究多态和继承的实现方式。 多态的底层实现 多态通过方法重写和方法重载来实现,方法重写是指子类重写父类的方法,而方法重载是指在同一个类中,两个或多个方法具有相同的名称,但具有不同的参数列表。 下面是一个多态的例子:…

    Java 2023年5月19日
    00
  • Spring MVC 拦截器 interceptor 用法详解

    Spring MVC 拦截器(Interceptor)用法详解 什么是拦截器 拦截器是Spring MVC框架中的一种增强处理器,拦截器也可以称为过滤器(Filter)或者AOP实现,它可以在请求处理的过程中预处理请求、处理请求和处理完请求后进行后续处理。拦截器可以将特定的处理逻辑应用到整个应用程序或者某个特定的Controller中。 和Servlet的过…

    Java 2023年5月20日
    00
  • Java实现基于token认证的方法示例

    我来为您讲解“Java实现基于token认证的方法示例”的完整攻略。 什么是token认证 Token认证是现在比较流行的Web应用程序认证方法之一。它能解决基于session认证的一些问题,比如跨站点请求伪造(CSRF)和分布式系统中的会话共享的问题。用户只需要通过用户名和密码一次验证,在服务器成功认证后,服务器会返回一个token给客户端。客户端在后续的…

    Java 2023年5月19日
    00
  • 使用eclipse + maven一步步搭建SSM框架教程详解

    下面就为您详细讲解如何使用eclipse + maven一步步搭建SSM框架。我们将从以下几个方面来介绍这个过程: 前置条件 创建Maven项目 添加依赖 创建实体类和Mapper接口 配置Spring和Mybatis 创建控制器和视图 示例1:查询所有用户信息 示例2:添加用户信息 1. 前置条件 在开始之前,请确认您已经安装并配置好了以下软件和环境: J…

    Java 2023年5月20日
    00
  • java开发SpringBoot参数校验过程示例教程

    下面我来详细讲解“Java开发Spring Boot参数校验过程示例教程”的完整攻略。 什么是参数校验 在Web开发中,为了保证数据的准确性和完整性,在接口中进行参数校验是一个很重要的环节。参数校验通常包括验证参数的格式、数据类型、取值范围等。 使用Spring Boot进行参数校验 Spring Boot提供了一种方便快捷的方式来进行参数校验。使用Spri…

    Java 2023年5月19日
    00
  • 详解SpringMVC重定向传参数的实现

    接下来我将为你讲解“详解SpringMVC重定向传参数的实现”的完整攻略。 标题 介绍 在SpringMVC中,有时候需要在重定向跳转的时候把一些参数传递过去,以便在下一个请求中使用。本文将详细讲解如何在SpringMVC中实现重定向传参数。 实现步骤 第一步:使用RedirectAttributes添加Flash属性 SpringMVC提供了Redirec…

    Java 2023年6月15日
    00
合作推广
合作推广
分享本页
返回顶部