拓扑排序,广度优先

使用一个队列来进行广度优先搜索。初始时,所有入度为 0 的节点都被放入队列中,它们就是可以作为拓扑排序最前面的节点,并且它们之间的相对顺序是无关紧要的。

在广度优先搜索的每一步中,取出队首的节点 u:

  •     将 u 放入答案中;
  •     移除 u 的所有出边,也就是将 u 的所有相邻节点的入度减少 1。如果某个相邻节点 v 的入度变为 0,那么就将 v 放入队列中。

在广度优先搜索的过程结束后。如果答案中包含了这 n 个节点,那么就找到了一种拓扑排序,否则说明图中存在环,也就不存在拓扑排序了。

    /**
     * 课程表 II,拓扑排序,宽度优先
     * @param numCourses 课程数
     * @param prerequisites
     * @return
     */
    public static int[] findOrder(int numCourses, int[][] prerequisites){
        int[][] edges = new int[numCourses][numCourses];    // 邻接矩阵存储有向图
        int[] inDeg = new int[numCourses];      // 各顶点入度
        int[] result = new int[numCourses];     // 结果
        int index = 0;
        for (int i = 0; i < prerequisites.length; i++) {    // 初始化
            int a1 = prerequisites[i][0], a2 = prerequisites[i][1];
            edges[a2][a1] = 1;
            inDeg[a1]++;
        }
        Deque<Integer> queue = new LinkedList<>();  //队列
        for (int i = 0; i < numCourses; i++) {
            if (inDeg[i] == 0){
                queue.add(i);   //入度为0的入队
            }
        }
        while (!queue.isEmpty()){
            int u = queue.poll();
            result[index++] = u;
            for (int i = 0; i < numCourses; i++) {
                if(edges[u][i] == 1){
                    inDeg[i]--;     // 以u为起始的,入度减一
                    if(inDeg[i] == 0)
                        queue.add(i);
                }
            }
        }
        if(index != numCourses){    // 有环,无解
            return new int[0];
        }
        return result;  //无环,返回结果,结果不唯一
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值