java搜索无向图中两点之间所有路径的算法

Java搜索无向图中两点之间所有路径的算法

算法思路

该算法使用深度优先搜索来查找两个节点之间的所有路径。在搜索期间,对于每个遍历到的未访问节点,我们可以标记它为已访问,并沿着它的所有未访问邻居递归搜索。在这个过程中,我们将到达一个目标节点作为目标终点,或遍历了所有的节点,这代表着没有路径可以到达目标终点,此时我们就回溯到上一步去探索其它可能的路径,直到找到所有的路径或者遍历完所有路径。

代码实现

代码实现分为如下几个步骤:

  1. 初始化所有节点为未访问状态,把起始节点添加到路径中,标记起始节点为已访问状态;
  2. 从起始节点开始深度优先搜索,对于每个遍历到的未访问节点,标记它为已访问,并将其添加到路径中;
  3. 如果当前节点为目标节点,则输出这个路径;
  4. 如果当前节点不是目标节点,则在继续递归搜索之前,搜索其所有未访问邻居节点;
  5. 回溯到上一个节点,回收资源,从路径中删除该节点并将其标记为未访问;
  6. 重复上述操作,直到搜索完所有路径。
public class Graph {
    private int V;
    private LinkedList<Integer>[] adj;

    public Graph(int v) {
        V = v;
        adj = new LinkedList[v];
        for (int i = 0; i < v; ++i) {
            adj[i] = new LinkedList();
        }
    }

    void addEdge(int v, int w) {
        adj[v].add(w); // Add w to v's list.
        adj[w].add(v); // Add v to w's list.
    }

    // A recursive function to print all paths from 'u' to 'd'.
    // visited[] keeps track of vertices in current path.
    // path[] stores actual vertices and path_index is current
    // index in path[]
    void printAllPathsUtil(int u, int d, boolean[] visited, int[] path, int pathIndex) {
        visited[u] = true;
        path[pathIndex] = u;
        pathIndex++;

        if (u == d) {
            for (int i = 0; i < pathIndex; i++) {
                System.out.print(path[i] + " ");
            }
            System.out.println("");
        } else {
            Iterator<Integer> i = adj[u].listIterator();
            while (i.hasNext()) {
                int n = i.next();
                if (!visited[n]) {
                    printAllPathsUtil(n, d, visited, path, pathIndex);
                }
            }
        }

        // Remove current vertex from path[] and mark it as unvisited
        pathIndex--;
        visited[u] = false;
    }

    void printAllPaths(int s, int d) {
        boolean[] visited = new boolean[V];
        int[] path = new int[V];
        int pathIndex = 0;
        // Initialize all vertices as not visited
        for (int i = 0; i < V; i++) {
            visited[i] = false;
        }

        // Call the recursive helper function to print all paths
        printAllPathsUtil(s, d, visited, path, pathIndex);
    }

    public static void main(String[] args) {
        Graph g = new Graph(4);
        g.addEdge(0, 1);
        g.addEdge(0, 2);
        g.addEdge(0, 3);
        g.addEdge(2, 0);
        g.addEdge(2, 1);
        g.addEdge(1, 3);

        int s = 2, d = 3;
        System.out.println("Following are all different paths from " + s + " to " + d);
        g.printAllPaths(s, d);
    }
}

示例说明

示例1

例如,我们有一个无向图,有四个节点,边的连接如下所示:

  0 ------- 1
  |         |
  |         |
  |         |
  2 ------- 3

我们要查找从节点2到节点3之间的所有路径,那么可以使用如下代码来实现:

Graph g = new Graph(4);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(0, 3);
g.addEdge(2, 0);
g.addEdge(2, 1);
g.addEdge(1, 3);

int s = 2, d = 3;
System.out.println("Following are all different paths from " + s + " to " + d);
g.printAllPaths(s, d);

输出结果为:

Following are all different paths from 2 to 3
2 0 1 3
2 1 3
2 0 3

可以看出,从节点2到节点3,有三条不同的路径,分别是2->0->1->3,2->1->3,2->0->3。

示例2

再例如,我们有一个无向图,有六个节点,边的连接如下所示:

     0 ----- 1
     |\     /|
     | \   / |
     |  \ /  |
     |   3   |
     |  / \  |
     | /   \ |
     |/     \|
     2 ----- 4
            |
            |
            |
            5

我们要查找从节点0到节点5之间的所有路径,那么可以使用如下代码来实现:

Graph g = new Graph(6);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(0, 3);
g.addEdge(1, 3);
g.addEdge(1, 4);
g.addEdge(2, 3);
g.addEdge(2, 4);
g.addEdge(3, 4);
g.addEdge(4, 5);

int s = 0, d = 5;
System.out.println("Following are all different paths from " + s + " to " + d);
g.printAllPaths(s, d);

输出结果为:

Following are all different paths from 0 to 5
0 1 3 4 5 
0 1 4 5 
0 2 3 4 5 
0 2 4 5 
0 3 4 5 

可以看出,从节点0到节点5,有五条不同的路径,分别是0->1->3->4->5,0->1->4->5,0->2->3->4->5,0->2->4->5,0->3->4->5。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java搜索无向图中两点之间所有路径的算法 - Python技术站

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

相关文章

  • springmvc fastjson 反序列化时间格式化方法(推荐)

    SpringMVC Fastjson 反序列化时间格式化方法 1. 什么是Fastjson? Fastjson是一个Java语言编写的高性能JSON处理器,它可以将Java对象转换为JSON格式的字符串,也可以将JSON格式的字符串转换为Java对象。Fastjson具有快速、简单、灵活等特点,是目前Java开发中最流行的JSON处理器之一。 2. Spri…

    Java 2023年5月18日
    00
  • jsp中获取当前目录的方法

    首先,要获取当前目录的绝对路径,可以使用request.getServletContext().getRealPath(“/”)方法。 具体实现步骤如下: 1.在JSP页面中嵌入Java代码块,使用request.getServletContext().getRealPath(“/”)获取当前目录的绝对路径。 <%@ page language=&qu…

    Java 2023年5月20日
    00
  • feign调用中文参数被encode编译的问题

    当我们使用Feign进行调用时,如果参数中含有中文或其他非ASCII字符,我们会发现这些参数被自动编码了,而且编码方式并不是我们常见的UTF-8,这就需要我们进行一些额外的配置来解决这个问题。 一般情况下,我们需要在Feign配置中添加一个编码器类,用于将参数编码成UTF-8格式,例如: @Configuration public class FeignCo…

    Java 2023年5月20日
    00
  • Java 数组的两种初始化方式

    Java 数组是一个特殊的变量,它能够存储一组有序的数据。在 Java 中,数组的初始化方式有两种: 1. 静态初始化 静态初始化就是在数组定义时就为数组元素分配空间,并赋初值。使用静态初始化的数组,数组的大小和元素的值都是确定的,不能进行修改。 示例一: // 定义一个 int 类型的数组 a int[] a = {1, 2, 3, 4, 5}; 示例二:…

    Java 2023年5月26日
    00
  • Java中String和StringBuffer及StringBuilder 有什么区别

    Java中String、StringBuffer和StringBuilder都是关于字符串的类,但它们有着不同的特点和用法。 String类 String类是Java中的一个不可变类,一旦声明并赋值,它的实际内容就无法再被改变了。这是由于它的内部实现是通过一个指向char数组的final引用来实现的。换句话说,一旦String对象被创建,这个引用就不能指向另…

    Java 2023年5月27日
    00
  • 基于SpringBoot实现代码在线运行工具

    基于 Spring Boot 实现代码在线运行工具的完整攻略 在本文中,我们将详细讲解如何基于 Spring Boot 实现代码在线运行工具的完整攻略。我们将使用 Spring Boot、Thymeleaf 和 JavaCompiler API 来实现这个工具。 步骤一:创建 Spring Boot 项目 首先,我们需要创建一个 Spring Boot 项目…

    Java 2023年5月15日
    00
  • 基于js实现投票的实例代码

    首先,基于js实现投票要考虑两个方面,其一是前端页面的实现,其二是后端接口的实现。 前端页面实现 前端页面主要包含页面布局和交互逻辑两个部分。 页面布局 可以使用HTML/CSS完成页面布局,页面布局可以按照个人需求自定义设计,以本次介绍的前端实现为例,可分为以下几个区域: 问题区:用于展示当前投票的问题 选项区:用于展示当前问题的选项内容 操作区:用于用户…

    Java 2023年6月15日
    00
  • 如何基于Java实现对象List排序

    当我们需要对一个对象List进行排序时,可以使用Java提供的Collections.sort()方法来完成排序操作。以下是基于Java实现对象List排序的完整攻略: 1. 定义一个对象类 首先,我们需要定义一个对象类,并实现Comparable接口。比较方式可以根据具体需求进行定义。假设我们要对学生对象进行排序,比较方式为按照学生年龄从小到大排序,则可以…

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