基于深度优先搜索的图遍历

这里写目录标题

基于深度优先搜索的无向图遍历

使用深度优先搜索遍历无向图,将无向图用邻接表存储:

算法流程图

  1. 初始化起点 source ,当前节点v 为起点,终点 target ,路径path 为空,路径集合 paths 为空
  2. 将当前节点v 添加到 path
  3. 判断当前节点v是否为终点,是转step4,否转step5
  4. 保存 pathpaths 中,转step7
  5. 获取当前节点的所有邻接点,用集合N表示
  6. 遍历N ,若 N_i 不在 path 中,令v =N_i ,转step2;若N_ipath 中,i +=1。
  7. 删除 path 中最后一个节点,令v =path中最后一个节点,转step5
  8. 以上步骤遍历了所有每一个点的邻接点,算法结束,输出起点到终点的所有路径paths

Python实现

python 复制代码
from typing import List


def dfs(adjacent_list, source, target):
    """
    :param adjacent_list: 邻接表
    :param source: 起点
    :param target: 终点
    :return: 起点-终点的所有路径
    """

    def dfs_helper(adjacent_list, source, current_node, target):

        path.append(current_node)  # 压栈
        if current_node == target:
            paths.append(path.copy())
        else:
            neighbors = adjacent_list[current_node]
            for neighbor in neighbors:
                if neighbor not in path:
                    dfs_helper(adjacent_list, source, neighbor, target)
        path.pop()  # 弹栈

    paths = []
    path = []
    dfs_helper(adjacent_list, source, source, target)
    return paths


if __name__ == "__main__":
    # 邻接表
    adjacent_list = {
        1: [2, 3],
        2: [1, 4, 5],
        3: [1, 4, 7],
        4: [2, 3, 5, 6, 7],
        5: [2, 4, 6],
        6: [4, 5],
        7: [3, 4]
    }
    # 深搜
    paths: List[List] = dfs(adjacent_list, 1, 6)

    [print(path) for path in paths]

Java实现

java 复制代码
package org.example;

import java.util.*;

public class DepthFirstSearch {
    //    List<Integer> path = new ArrayList<>();
    Stack<Integer> path = new Stack<>();
    List<List<Integer>> paths = new ArrayList<>();

    void dfs(Map<Integer, List<Integer>> adjacent_list, int source, int current_node, int target) {
        path.push(current_node);
        if (current_node == target) {
            paths.add(new ArrayList<>(path));
            path.remove(path.size() - 1);
        } else {
            List<Integer> neighbors = adjacent_list.get(current_node);
            for (Integer neighbor : neighbors) {
                if (!path.contains(neighbor)) {
                    dfs(adjacent_list, source, neighbor, target);
                }
            }
            path.pop();
        }
    }

    public static void main(String[] args) {
        Map<Integer, List<Integer>> adjacent_list = new HashMap<>();
        adjacent_list.put(1, Arrays.asList(2, 3));
        adjacent_list.put(2, Arrays.asList(1, 4, 5));
        adjacent_list.put(3, Arrays.asList(1, 4, 7));
        adjacent_list.put(4, Arrays.asList(2, 3, 5, 6, 7));
        adjacent_list.put(5, Arrays.asList(2, 4, 6));
        adjacent_list.put(6, Arrays.asList(4, 5));
        adjacent_list.put(7, Arrays.asList(3, 4));
        System.out.println(adjacent_list);

        DepthFirstSearch dfs = new DepthFirstSearch();
        dfs.dfs(adjacent_list, 1, 1, 6);
        for (List<Integer> path : dfs.paths) {
            System.out.println(path);
        }

    }
}

基于深度优先搜索的有向图遍历

和无向图遍历一样,建立邻接矩阵即可。

Python实现

python 复制代码
from typing import List, Tuple, Any, Dict
import networkx
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from typing import List


def paint_topological_graph(nodes,
                            edges: List[Tuple],
                            coordinates: Dict[Any, Tuple] = None,
                            directed=False
                            ):
    print(nodes)
    print(edges)
    print(coordinates)

    graph = networkx.DiGraph() if directed else networkx.Graph()  # 全连通 有向图
    graph.add_nodes_from(nodes)
    graph.add_edges_from(edges)
    networkx.draw(graph, pos=coordinates, with_labels=True, node_color='red', )

    plt.show()
    print(networkx.has_path(graph, 1, 12))
    return graph


def dfs(adjacent_list, source, target):
    """
    :param adjacent_list: 邻接表
    :param source: 起点
    :param target: 终点
    :return: 起点-终点的所有路径
    """

    def dfs_helper(adjacent_list, source, current_node, target):

        path.append(current_node)
        if current_node == target:
            paths.append(path.copy())
            path.pop()
        else:
            neighbors = adjacent_list[current_node]
            for neighbor in neighbors:
                if neighbor not in path:
                    dfs_helper(adjacent_list, source, neighbor, target)
            path.pop()

    paths = []
    path = []
    dfs_helper(adjacent_list, source, source, target)
    return paths


if __name__ == "__main__":
    # 点坐标
    node_coord = {
        1: (1, 0), 2: (1, 3), 3: (2.5, 3), 4: (2, 2.5), 5: (3, 2), 6: (2, 1.5), 7: (3, 0), 8: (6, 0), 9: (5.5, 2),
        10: (5.5, 3), 11: (6, 4), 12: (0, 0), 13: (0, 1), 14: (5.5, 0.5), 15: (4.5, 0.5), 16: (5, 5),
    }

    edges = [
        (13, 12), (1, 2), (2, 4), (2, 3), (4, 3), (4, 5), (1, 6), (1, 7), (6, 7), (6, 5), (7, 8), (5, 9), (5, 10),
        (3, 11), (11, 10), (9, 8), (10, 9), (8, 11), (14, 15), (8, 14), (12, 1), (11, 16),
    ]

    # 画图
    paint_topological_graph(nodes=np.arange(1, 17, 1),
                            edges=edges,
                            directed=True,
                            coordinates=node_coord
                            )
    # 邻接表
    adjacent_list = {
        1: [2, 6, 7],
        2: [3, 4],
        3: [11],
        4: [3, 5],
        5: [9, 10],
        6: [5, 7],
        7: [8],
        8: [11, 14],
        9: [8],
        10: [9],
        11: [10, 16],
        12: [1],
        13: [12],
        14: [15],
        15: [],
        16: [],
    }
    # 深搜
    paths: List[List] = dfs(adjacent_list, 1, 11)

    [print(path) for path in paths]
相关推荐
烁3476 分钟前
每日一题(小白)动态规划篇2
算法·动态规划
风象南6 分钟前
Spring Boot 实现文件秒传功能
java·spring boot·后端
橘猫云计算机设计7 分钟前
基于django优秀少儿图书推荐网(源码+lw+部署文档+讲解),源码可白嫖!
java·spring boot·后端·python·小程序·django·毕业设计
黑猫Teng11 分钟前
Spring Boot拦截器(Interceptor)与过滤器(Filter)深度解析:区别、实现与实战指南
java·spring boot·后端
互联网杂货铺14 分钟前
如何用Postman实现自动化测试?
自动化测试·软件测试·python·测试工具·测试用例·接口测试·postman
星河浪人17 分钟前
Spring Boot启动流程及源码实现深度解析
java·spring boot·后端
佩奇的技术笔记18 分钟前
中级:Maven面试题精讲
java·面试·maven
予安灵21 分钟前
一文详细讲解Python(详细版一篇学会Python基础和网络安全)
开发语言·python
Lizhihao_29 分钟前
JAVA-堆 和 堆排序
java·开发语言
极客先躯34 分钟前
高级java每日一道面试题-2025年3月21日-微服务篇[Nacos篇]-什么是Nacos?
java·开发语言·微服务