图的拓扑排序--Khan算法

大家在上大学的时候,应该都遇到过这样的情况,有些高级的课程需要你先完成基础课程后才可以学习。在「图11. 课程关系图」中,如果你想选课程 C,那你需要先完成课程 B,如果你想选课程 B,那么你需要先完成课程 A。

此时,就需要「拓扑排序」的帮忙了。「拓扑排序」针对的是 有向无环图 的一种算法。它是对「图」中所有顶点按照先后顺序的一种线性排序。换句话说,在如果存在顶点 u 和顶点 v,要想到达顶点 v,则必须要到达顶点 u 。那么在「拓扑排序」中,顶点 u 必须处于顶点 v 的前面。

Khan算法的步骤如下:

  1. 创建一个degree数组用来记录每个点当前的入度,并将所有值初始化为0
  2. 遍历所有边,更新degree数组
  3. 创建队列
  4. 若队列不空,出队一个点,记录在排序数组中,将degree对应位置设为-1,找到所有由它出发可以直接到达的点,将这些点的degree全部减一。
  5. 遍历degree数组,将找到的第一个值为0的点入队。
  6. 当队列不空时循环45两步。

课程表 II

现在你总共有 numCourses 门课需要选,记为 0 到 numCourses - 1。给你一个数组 prerequisites ,其中 prerequisites[i] = [ai, bi] ,表示在选修课程 ai 前 必须 先选修 bi 。

例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示:[0,1] 。
返回你为了学完所有课程所安排的学习顺序。可能会有多个正确的顺序,你只要返回 任意一种 就可以了。如果不可能完成所有课程,返回 一个空数组 。

 为了提高效率,我们把边转化成邻接矩阵的形式存储。

public class Solution {
    public int[] FindOrder(int numCourses, int[][] prerequisites) {
        int[] res=new int[numCourses];
        if(numCourses==1)
        {
            res[0]=0;
            return res;
        }
        int[] degree=new int[numCourses];
        bool[,] matrix=new bool[numCourses,numCourses];
        for(int i=0;i<numCourses;i++)
        {
            degree[i]=0;
            for(int j=0;j<numCourses;j++)
                matrix[i,j]=false;
        }
        for(int i=0;i<prerequisites.Length;i++)
        {
            degree[prerequisites[i][0]]++;
            matrix[prerequisites[i][1],prerequisites[i][0]]=true;
        }
        Queue<int> q=new Queue<int>();
        int a=0;
        do
        {
            if(q.Count!=0)
            {
                int degree0=q.Dequeue();
                res[a++]=degree0;
                degree[degree0]=-1;
                for(int i=0;i<numCourses;i++)
                if(matrix[degree0,i])
                degree[i]--;
            }
            for(int i=0;i<numCourses;i++)
            if(degree[i]==0)
            {
                q.Enqueue(i);
                break;
            }
        }while(q.Count!=0);
        if(a==numCourses)
        return res;
        else
        {
            int[] empty=new int[0];
            return empty;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_43533956/article/details/124180422
今日推荐