Topological Sorting lintcode

本文深入探讨了拓扑排序算法的核心概念及其应用,并通过实例演示了使用广度优先搜索(BFS)实现拓扑排序的过程。重点介绍了算法的复杂度分析和具体代码实现。

Given an directed graph, a topological order of the graph nodes is
defined as follow:

For each directed edge A -> B in graph, A must before B in the order
list. The first node in the order can be any node in the graph with no
nodes direct to it. Find any topological order for the given graph.

广度优先搜索法

思路

拓扑排序算法的基本步骤:

  1. 构造一个队列Q(queue) 和 拓扑排序的结果队列T(topological);

  2. 把所有没有依赖顶点的节点放入Q;

  3. 当Q还有顶点的时候,执行下面步骤:

    3.1 从Q中取出一个顶点n(将n从Q中删掉),并放入T(将n加入到结果集中); 
    3.2 对n每一个邻接点m(n是起点,m是终点); 
        3.2.1 去掉边<n,m>; 
        3.2.2 如果m没有依赖顶点,则把m放入Q;

先遍历所有顶点的neighbor列表, 用一个hashmap来记录每个点的入度. 将入度为0的点入队列. 当队列还有顶点时候从队列里弹出一个点, 把它的neighbor列表里的节点的入度都-1, 如果有入度为0的就继续进入队列.

复杂度

首先获得节点的入度数,时间复杂度为 O(V+E), 使用了哈希表存储,空间复杂度为 O(V). 遍历图求得入度为0的节点,时间复杂度为 O(V). 用BFS方法遍历复杂度为O(V+E)故时间复杂度为 O(V+E)O(V+E). 空间为O(V)

代码

public ArrayList<DirectedGraphNode> topSort(ArrayList<DirectedGraphNode> graph) {
    ArrayList<DirectedGraphNode> res = new ArrayList<DirectedGraphNode>();
    if (graph == null || graph.size() == 0) {
        return res;
    }
    HashMap<DirectedGraphNode, Integer> map = new HashMap<DirectedGraphNode, Integer>();
    for (DirectedGraphNode node : graph) {
        for (DirectedGraphNode cur : node.neighbors) {
            //写入每个节点的入度
            if (map.containsKey(cur)) {
                map.put(cur, map.get(cur) + 1);
            } else {
                map.put(cur, 1);
            }
        }
    }
    Queue<DirectedGraphNode> queue = new LinkedList<DirectedGraphNode>();
    for (DirectedGraphNode node : graph) {
        if (!map.containsKey(node)) {
            queue.offer(node);
            res.add(node);
        }
    }
    while (!queue.isEmpty()) {
        DirectedGraphNode cur = queue.poll();
        for (DirectedGraphNode node : cur.neighbors) {
            map.put(node, map.get(node) - 1);
            if (map.get(node) == 0) {
                queue.offer(node);
                res.add(node);
            }
        }
    }
    return res;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值