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

这里写目录标题

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

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

算法流程图

  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]
相关推荐
mghio7 小时前
Dubbo 中的集群容错
java·微服务·dubbo
咖啡教室12 小时前
java日常开发笔记和开发问题记录
java
咖啡教室12 小时前
java练习项目记录笔记
java
用户277844910499313 小时前
借助DeepSeek智能生成测试用例:从提示词到Excel表格的全流程实践
人工智能·python
鱼樱前端13 小时前
maven的基础安装和使用--mac/window版本
java·后端
RainbowSea13 小时前
6. RabbitMQ 死信队列的详细操作编写
java·消息队列·rabbitmq
RainbowSea14 小时前
5. RabbitMQ 消息队列中 Exchanges(交换机) 的详细说明
java·消息队列·rabbitmq
算AI15 小时前
人工智能+牙科:临床应用中的几个问题
人工智能·算法
JavaEdge在掘金15 小时前
ssl.SSLCertVerificationError报错解决方案
python