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日

相关文章

  • java实现可逆加密算法

    要实现可逆加密算法,我们可以通过以下步骤来完成: 步骤一:选择加密算法 首先,我们需要选择一种可逆的加密算法。常见的可逆加密算法有DES、AES、RSA等。这里我们选择AES算法作为例子。 步骤二:确定加密参数 在选择了加密算法之后,我们需要确定加密参数。对于AES算法来说,有三个参数需要确定:密钥长度、加密模式和填充方式。常见的密钥长度为128位、192位…

    Java 2023年5月19日
    00
  • Java编程实现时间和时间戳相互转换实例

    Java编程实现时间和时间戳相互转换实例 时间和时间戳 在Java中,时间通常用时间戳(timestamp)表示,其是一个long型的整数,表示自1970年1月1日00:00:00以来经过的毫秒数,也就是Unix时间戳。 而时间则通常用Java中的Date、Calendar或SimpleDateFormat等封装类表示。 时间戳转换为时间 我们首先来看如何将…

    Java 2023年5月20日
    00
  • centOS7安装jdk1.8的方法

    当我们需要在CentOS 7服务器上安装Java开发工具包(JDK)1.8时,我们可以按照以下步骤进行操作: 步骤一:检查并更新系统包管理器 在开始安装过程前,建议先通过以下命令检查系统中是否已安装其他版本的JDK: java -version 如果输出结果显示当前系统中没有安装任何版本的JDK,则允许继续操作;如果已安装其它版本的JDK,则需要卸载旧版本,…

    Java 2023年5月19日
    00
  • java日常练习题,每天进步一点点(1)

    下面是对java日常练习题攻略的详细讲解。 1. 确定学习目标 在开始学习之前,我们必须了解我们的学习目标。在这个练习题中,我们的目标是通过每天练习一点点,提高自己的Java编程技能。 2. 确定练习内容 在了解学习目标之后,我们需要选择适合自己的练习内容。这个练习题提供了很多经典的Java练习题,包括基础语法、算法、数据结构、面向对象等方面的内容。 3. …

    Java 2023年5月23日
    00
  • MyBatis详细执行流程的全纪录

    MyBatis详细执行流程的全纪录 MyBatis是一款基于Java的持久层框架,提供了丰富的SQL映射支持和灵活的结果映射配置。本文将介绍MyBatis的执行流程,并通过两个示例来详细讲解。 执行流程 MyBatis的执行流程主要分为以下几个步骤: 加载配置文件:MyBatis的配置文件包含了一系列的配置信息,例如数据库连接信息、SQL映射文件的位置和类型…

    Java 2023年5月20日
    00
  • Springboot整合多数据源配置流程详细讲解

    下面我将为你详细讲解Springboot整合多数据源配置流程的完整攻略。 1. 引入多数据源依赖 在 pom.xml 文件中引入多数据源依赖。这里我们以 Druid 数据源为例,示例代码如下: <dependency> <groupId>com.alibaba</groupId> <artifactId>dru…

    Java 2023年5月20日
    00
  • java实现文件拷贝的七种方式

    我来为你讲解“Java实现文件拷贝的七种方式”的攻略。以下是这七种方式: 1. 使用字节流(InputStream和OutputStream)进行拷贝 字节流是Java I/O中的基本类,可以方便地进行文件拷贝。我们可以使用 FileInputStream 读取源文件,将数据写入 FileOutputStream 中实现文件拷贝。具体代码如下: public…

    Java 2023年5月20日
    00
  • spring boot请求异常处理并返回对应的html页面

    当我们在开发Spring Boot应用时,可能会遇到很多请求异常的情况。如何处理这些异常并且返回对应的HTML页面呢?下面我将会为您提供一份完整的攻略。 步骤1:添加依赖 要实现请求异常处理并返回对应的HTML页面,我们需要添加thymeleaf和spring-boot-starter-web两个依赖。 在pom.xml文件中添加以下依赖: <depe…

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