• 拓扑排序


    1. 什么是拓扑排序?

    对于任何有向图而言,其拓扑排序为其所有结点的一个线性排序(对于同一个有向图而言可能存在多个这样的结点排序)。该排序满足这样的条件——对于图中的任意两个结点uv,若存在一条有向边从u指向v,则在拓扑排序中 u 一定出现在 v 前面。

    拓扑排序主要用来解决有向图中的依赖解析(dependency resolution)问题。

    2. 拓扑排序存在的条件?

    当且仅当一个有向图为有向无环图(directed acyclic graph,或称DAG)时,才能得到对应于该图的拓扑排序。

    3. 算法的实现

    通过队列实现:

    • 寻找入度为 0 的结点,将其放入队列中。
    • 依次将队列中的点取出,并将该点所指向的邻接点的入度减 1
      • 如果该节点的入度变为 0,则将其加入队列,否则不做任何操作
    • 当队列为空的时候判断,是否每一个结点均被访问过。若均被访问过则出队序列则为即为符合条件的一个拓扑队列,否则不存在拓扑队列。

    4. 代码

    class Solution {
        /**
         * 邻接表结点
         */
        public class Node{
            public int degree;
            public List<Integer> list;
    
            public Node(){
                this.degree = 0;
                this.list = new ArrayList<>();
            }
        }
    
        /**
         * @param numCourses 表示结点的数目
         * @param prerequisites 表示结点之间的关系
         */
        public boolean canFinish(int numCourses, int[][] prerequisites) {
            Node[] nodes = new Node[numCourses];
            Queue<Node> que = new LinkedList<>();
            int s = 0, e = 0, cnt = numCourses;
    
            //初始化
            for(int i = 0; i < numCourses; ++i){
                nodes[i] = new Node();
            }
    
            //构建邻接表
            for(int i = 0; i < prerequisites.length; ++i){
                s = prerequisites[i][1];
                e = prerequisites[i][0];
    
                nodes[s].list.add(e);
                nodes[e].degree++;
            }
    
            //拓扑排序
            for(int i = 0; i < numCourses; ++i){
                if(nodes[i].degree == 0){
                    que.add(nodes[i]);
                    cnt--;
                }
            }
    
            while(!que.isEmpty()){
                Node tnode = que.peek();
                que.poll();
    
                for(int i = 0; i < tnode.list.size(); ++i){
                    if(--nodes[tnode.list.get(i)].degree == 0){
                        que.add(nodes[tnode.list.get(i)]);
                        cnt--;
                    }
                }
            }
    
            //判断
            if(cnt != 0){
                return false;
            }
    
            return true;
        }
    }
    
  • 相关阅读:
    QT 信号槽 异步事件驱动 单线程 多并发
    Qt 静态库与共享库(动态库)共享配置的一个小办法
    关于:有符号与无符号整数的大小比较
    QT信号槽 中的对象野指针
    Qt程序打包发布
    Qt程序打包发布
    SQL Server 2012 sa 用户登录 18456 错误 (转)
    QtCreator常用之快捷键
    opengl中相关的计算机图形变换矩阵之:模型视图几何变换
    opengl中相关的计算机图形变换矩阵之:齐次坐标 (摘编)
  • 原文地址:https://www.cnblogs.com/zcxhaha/p/11409214.html
Copyright © 2020-2023  润新知