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

这里写目录标题

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

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

算法流程图

  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]
相关推荐
喜欢吃豆13 小时前
从指令遵循到价值对齐:医疗大语言模型的进阶优化、对齐与工具集成综合技术白皮书
人工智能·python·语言模型·自然语言处理·大模型·强化学习·constitutional
JAVA学习通13 小时前
SpringBoot Layui ThymeLeaf 一点点学习心得
java·spring
Access开发易登软件13 小时前
Access调用Azure翻译:轻松实现系统多语言切换
后端·python·低代码·flask·vba·access·access开发
考虑考虑13 小时前
JDK25中的StructuredTaskScope
java·后端·java ee
yumgpkpm13 小时前
CMP (类Cloudera) CDP7.3(400次编译)在华为鲲鹏Aarch64(ARM)信创环境中的性能测试过程及命令
大数据·hive·hadoop·python·elasticsearch·spark·cloudera
雨过天晴而后无语13 小时前
Windchill的codebase目录打成jar
java·jar
SimonKing13 小时前
「String到Date转换失败」:深挖@RequestBody的日期坑
java·后端·程序员
Rubisco..14 小时前
牛客周赛 Round 111
数据结构·c++·算法
兮山与14 小时前
算法8.0
算法
qq_124987075314 小时前
基于Spring Boot的网上招聘服务系统(源码+论文+部署+安装)
java·spring boot·后端·spring·计算机外设