拓扑排序(解决具有依赖性关系的问题)

Posted 秦枫-_-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了拓扑排序(解决具有依赖性关系的问题)相关的知识,希望对你有一定的参考价值。

拓扑排序是对一个有向图的顶点进行排序。它关心的是图中各个顶点的连接关系,这种连接关系也叫拓扑关系,因为它不关心各个顶点的位置与距离。

应用:

在一个有向无回路图中,要求对所有的节点进行排序。

先统计所有节点的入度,对于入度为0的节点就可以分离出来,然后把这个节点关联的节点的入度减一。

一直做改操作,直到所有的节点都被分离出来。

如果最后不存在入度为0的节点,那就说明有环,不存在拓扑排序,也就是很多题目的无解的情况。

下面是演示过程。


举例:力扣113 课程顺序

解题思路:

由题目给出一个有向无回路图,才能使得有可能的结果输出,图中任意两个点要么有先后关系,要么无关,
那么我们可以发现入度为0的点就是最先应该选修的课程,也就是我们的基础课程,其次修完这批课后,所有跟这些点关联的点入度减一,再在剩余的课中找出
基础课程,如此类推即可找出选课顺序,我们可以考虑用哈希表记录依赖关系,用数组记录每个点的入读,同时用队列维护入度为0的点

class Solution 
    public int[] findOrder(int numCourses, int[][] prerequisites) 
    Map<Integer,List<Integer>> map=new HashMap<>();//记录指向关系
    int []indeg=new int[numCourses];//记录每个点的入度
    for(int i=0;i<prerequisites.length;i++)
        List<Integer> list=map.getOrDefault(prerequisites[i][1],new ArrayList<>());
        list.add(prerequisites[i][0]);
        map.put(prerequisites[i][1],list);
        indeg[prerequisites[i][0]]++;
    
    Queue<Integer> q=new LinkedList<>();
    for(int i=0;i<numCourses;i++)
        if(indeg[i]==0)
        q.offer(i);
    
    int idx=0;
    int []ans=new int[numCourses];
    while(!q.isEmpty())
        int top=q.poll();
        ans[idx]=top;
        idx++;
         List<Integer> list=map.getOrDefault(top,new ArrayList<>());
        for(int i=0;i<list.size();i++)
            int ch=list.get(i);
           indeg[ch]--;
           if(indeg[ch]==0)
            q.offer(ch);
            
        
    
    if(idx<numCourses)return new int[];
    return ans;
    

以上是关于拓扑排序(解决具有依赖性关系的问题)的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode编程训练 - 拓扑排序(Topological Sort)

图的应用——拓扑排序(判断有向图有无回路)

图的应用——拓扑排序算法

拓扑排序

拓扑排序问题

UVA 10305 Ordering Tasks (拓扑排序)