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;
}

lpy1990
26 声望10 粉丝

引用和评论

0 条评论