拓扑排序【邻接矩阵&邻接表】

拓扑排序

拓扑排序【邻接矩阵&邻接表】_第1张图片

TuoPuSort

一、概念

我们再说拓扑排序时,我们首先了解下​DAG

将有向无环图G=(V,E)中的所有顶点排成一个线性序列,使图中任意一对顶点u,v,之间不存在环路

DAG是一种特殊的有向图,它由一组顶点和一组有向边组成,且不存在任何环路。

  • 每个顶点表示一个任务或操作,而有向边表示任务之间的依赖关系。
  • 在有向无环图中,从任意顶点出发沿着有向边行走,不会回到起始顶点。

拓扑排序:

看完上面,我们说下拓扑排序,这玩意儿的出现就是针对有向无环图,通过此算法,找出邮箱无环图的序列

注意: 拓扑排序的序列是不唯一的

算法描述:

使用邻接矩阵的代码如下: 【不懂,就画图,每个新序列按照一步步去拆解】

 /**
  * @param1: 邻接矩阵,adjMatrix[i][j] = 0 表示节点 i 和 j 之间没有边直接相连
  * @return: 拓扑序列
  * @description: 对用邻接表 adjMatrix 表示的图进行拓扑排序
  */
 public static int[] tuopuSort(int[][] adjMatrix){
     //n表示图中的节点数
     int n=adjMatrix.length;
     //计算图中每个节点的入度,inDegree[i]=j 表示节点i 的入度为j
     int[] inDegree=new int[n];
     for(int j=0;j<n;j++){
         for(int i=0;i<n;i++){
             if(adjMatrix[i][j]!=0){
                 inDegree[j]++;
             }
         }
     }
     //将入度为0的节点加入到队列中
     Queue<Integer> queue=new LinkedList<>();
     for(int i=0;i<n;i++){
         if(inDegree[i]==0){
             queue.offer(i);
         }
     }
     //记录拓扑序列
     int[] order=new int[n];
     //记录遍历节点的顺序
     int cnt=0;
     //通过BFS算法完成拓扑序列
     while(!queue.isEmpty()){
         //取出队首节点
         int cur=queue.poll();
         //取出节点的顺序即为拓扑排序的结果(这里就是开始记录,拓扑排序的齿轮转动了)
         order[cnt]=cur;
         cnt++;
         //遍历当前节点cur所指向的所有节点
         for(int next=0;next<n;next++){
             if(adjMatrix[cur][next]!=0){
                 //去掉cur指向next的边,故next的入度减1
                 inDegree[next]--;
                 //将入度为0的节点再次加入队列
                 if(inDegree[next]==0){
                     queue.offer(next);
                 }
             }
         }
     }
     if(cnt!=n){
         //图中存在环,拓扑排序不存在
         return new int[]{};
     }else{
         return order;
     }
 }

使用邻接表

 /**
  * @param1: 邻接表,adjList[i] 中存储节点 i 指向的节点
  * @param2: 图的节点数
  * @return: 拓扑序列
  * @description: 对用邻接表 adjList 表示的图进行拓扑排序
  */
 public static int[] tuopuSort(List<Integer>[] adjList,int n){
     //计算图中每个节点的入度,inDegree[i]=j表示节点i的入度为j
     int[] inDegree=new int[n];
     for(List<Integer> list:adjList){
         for(Integer node: list){
             inDegree[node]++;
         }
     }
     //将入度为0的节点加入到队列中
     Queue<Integer> queue=new LinkedList<>();
     for(int i=0;i<n;i++){
         if(inDegree[i]==0){
             queue.offer(i);
         }
     }
     //记录拓扑排序---->  如果图中存在环,拓扑排序不存在
     return cnt!=len?new int[]{}:order;
 }
 

你可能感兴趣的:(Grammar)