博客
关于我
Lintcode: Topological Sorting
阅读量:804 次
发布时间:2023-01-31

本文共 3018 字,大约阅读时间需要 10 分钟。

有向图的拓扑排序是数据处理和算法设计中的一个常见问题。拓扑排序使得我们可以确定一个顺序,使得对于图中的每一条有向边A→B,A在序列中都出现在B之前。以下将介绍两种常用的方法:一种基于广度优先搜索(BFS),另一种基于深度优先搜索(DFS)。

方法一:BFS实现

这种方法的核心思想是逐步构建结果列表,确保每次添加一个节点时,该节点是当前图中没有入边的节点。

  • 初始化

    • 创建一个空的结果列表res
    • 构建一个映射(如哈希表)inEdges,记录每个节点的入边节点。
    • 遍历所有节点,初始化每个节点的入边计数为0。
  • 开始过程

    • 进入一个循环,直到图中没有未被处理的节点为空。
    • 在循环内,先寻找所有入边计数为0的节点。
    • 从这些节点中选一个,加入结果列表res
    • 更新图中所有指向该节点的节点的入边计数。
  • 示例代码

    public class Solution {    public ArrayList topSort(ArrayList graph) {        ArrayList res = new ArrayList();        if (graph.isEmpty()) return res;        Map nodeMap = new HashMap();        for (DirectedGraphNode node : graph) {            nodeMap.put(node, new HashSet());        }        for (DirectedGraphNode node : graph) {            for (int i = 0; i < node.neighbors.size(); i++) {                nodeMap.get(node.neighbors.get(i)).add(node);            }        }        while (!graph.isEmpty()) {            int index = 0;            while (index < graph.size()) {                DirectedGraphNode cur = graph.get(index);                if (nodeMap.get(cur).isEmpty()) {                    res.add(cur);                    graph.remove(index);                    for (DirectedGraphNode elem : graph) {                        if (nodeMap.get(elem).contains(cur)) {                            nodeMap.get(elem).remove(cur);                        }                    }                } else {                    index++;                }            }        }        return res;    }}

    方法二:DFS实现

    这种方法采用深度优先搜索,确保每次处理一个节点时,先处理它的所有前置节点。

  • 初始化

    • 创建一个记录节点状态的映射status,用于区分未处理、处理中以及已处理状态。
    • 初始化结果列表res为空。
  • DFS过程

    • 在一个循环中,每次找到一个未被访问的节点,立即处理它的所有邻接点。
    • 将当前节点加入结果列表后,递归处理所有邻接点。
  • 示例代码

    public class Solution {    public ArrayList topSort(ArrayList graph) {        ArrayList res = new ArrayList();        if (graph.isEmpty()) return res;        Map status = new HashMap();        for (DirectedGraphNode elem : graph) {            status.put(elem, 0);        }        ArrayList templist = new ArrayList();        templist.add(null);        while (hasUnvisited(graph, status, templist)) {            DirectedGraphNode cur = templist.get(0);            templist.set(0, null);            search(cur, status, res);        }        return res;    }    public boolean hasUnvisited(ArrayList graph, Map status, ArrayList templist) {        for (DirectedGraphNode elem : graph) {            if (status.get(elem) == 0) {                templist.set(0, elem);                return true;            }        }        return false;    }    public void search(DirectedGraphNode cur, Map status, ArrayList res) {        if (status.get(cur) == 1) {            System.out.println("不是DAG");            return;        }        if (status.get(cur) == 2) {            return;        }        status.put(cur, 1);        for (DirectedGraphNode neigh : cur.neighbors) {            search(neigh, status, res);        }        status.put(cur, 2);        res.add(0, cur);    }}

    总结

    以上两种方法都可以实现对有向图的拓扑排序,无论是BFS还是DFS,都可以奏效。但选择哪种方法取决于具体的应用场景和性能需求。BFS方法通常更为简单,实现起来也较为直接;而DFS方法则允许灵活的选择,甚至可以通过修改实现来支持不同的拓扑排序风格。

    转载地址:http://bywfk.baihongyu.com/

    你可能感兴趣的文章
    Nginx代理外网映射
    查看>>
    Nginx代理模式下 log-format 获取客户端真实IP
    查看>>
    Nginx代理解决跨域问题(导致图片只能预览不能下载)
    查看>>
    Nginx代理访问提示ERR_CONTENT_LENGTH_MISMATCH
    查看>>
    Nginx代理配置详解
    查看>>
    Nginx代理静态资源(gis瓦片图片)实现非固定ip的url适配网络环境映射ip下的资源请求解决方案
    查看>>
    Nginx代理静态资源(gis瓦片图片)实现非固定ip的url适配网络环境映射ip下的资源请求解决方案
    查看>>
    nginx反向代理
    查看>>
    Nginx反向代理
    查看>>
    nginx反向代理、文件批量改名及统计ip访问量等精髓总结
    查看>>
    Nginx反向代理与正向代理配置
    查看>>
    Nginx反向代理及负载均衡实现过程部署
    查看>>
    Nginx反向代理和负载均衡部署指南
    查看>>
    Nginx反向代理是什么意思?如何配置Nginx反向代理?
    查看>>
    nginx反向代理解决跨域问题,使本地调试更方便
    查看>>
    nginx反向代理转发、正则、重写、负摘均衡配置案例
    查看>>
    Nginx反向代理配置
    查看>>
    Nginx启动SSL功能,并进行功能优化,你看这个就足够了
    查看>>
    nginx启动脚本
    查看>>
    Nginx在Windows上和Linux上(Docker启动)分别配置基本身份认证示例
    查看>>