图的遍历算法分析及应用(3)--拓扑排序

    对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若 ∈E(G),则u在线性序列中出现在v之前。如下图

    拓扑排序序列还可以为:C1,C3,C2,C4,C6,C5,C7当然还有别的可能。对于这些基础概念在此就不在强调,相信学过学过数据结构的同学,都知道它的概念,在此我们只要来看看拓扑排序的算法实现,以及各种算法的分析。

   

 实现1:

bool TopologicalSortingVer1(int G[][Max],int Result[])
{
      // 时间复杂度o(n~3)
      int i,j,k;
      bool Visit[Max];
      for(i=0;i

      for(k=0;k             for(i=0;i                  if(Visit[i])continue;
                 for(j=0;j                        if(G[j][i]==1)break;
                 }
                if(j                 Visit[i]=true;
                for(j=0;j                 Result[k]=i;
                break;
          }
      if(i>=Max) return false;
    }
    return true;
}

    这是一种很直接的想法,最外层的K循环,表示已经排序的个数,第二层的循环i表示从n个顶点中寻找一个还没有被排序的顶点(每次只找一个,当然可以改进,找多个),一旦找到,再判断这个顶点的入度是否为零,这就是第三层循环j。一旦不能找到这样入度为零的顶点了,排序结束,即存在有向圈。 这种算法的时间复杂度o(n~2)

 

 

 实现2:

void GetdInDegree(int G[][Max],int Degree[])
{
     for(int i=0;i         Degree[i]=0;
        for(int j=0;j              Degree[i]+=G[j][i];
     }
}

bool TopologicalSortingVer2(int G[][Max],int Result[])
{
      using std::stack;
      // 时间复杂度
      int i,j;
      int Degree[Max];
      stack Mystack;

      GetdInDegree(G,Degree);//o(n~2)或o(e);
      for(i=0;i            if(Degree[i]==0)Mystack.push(i);
   
     int Count=0;
     while(!Mystack.empty()){
          Result[Count]=Mystack.top();
          Mystack.pop();
          for(j=0;j                if(G[Result[Count]][j]==1){
                     Degree[j]--;
                     if(Degree[j]==0)Mystack.push(j);
               }
          Count++;
      }

     //while循环的时间复杂度分析类型与深度优先搜索,每个元素仅仅进出栈一次,在每一次出栈后寻找他的邻接点(邻接表储存矩阵时o(n)邻接表储存时o(e_1),)
     //所以while循环时间复杂度为o(n~2)或o(e)
     if(Count      return true;  
     //所以总的时间度为o(n~2)或o(n+e);
}

   这种版本i就是数据结构(严蔚敏版本)书中介绍的,在此就不多说了。

   

 

实现3:

int Index=Max-1;
void DFS_TopologicalSorting(int G[][Max],int BeginVer,int Result[])
{
      Visited[BeginVer]=true;
      for(int i=0;i           if(IsEdgeFuncion(G,BeginVer,i)&&!Visited[i]){
                 DFS_TopologicalSorting(G,i,Result);
          }
      Result[Index--]=BeginVer;
}


bool TopologicalSortingVer3(int G[][Max],int Result[],bool(*IsEdgeFun)(int G[][Max],int, int))
{
       int i,BeginVer=0;
       for(i=0;i        IsEdgeFuncion=IsEdgeFun;

       DFS_TopologicalSorting(G,BeginVer,Result);
       if(Index>=0)return false;
       else return true;
       //时间复杂度类似于深度优先遍历为:o(n~2)或o(n+e)
}

数据结构书中提到过,可以利用深度优先来实现拓扑排序,但没有给出实现,在此我们利用深度优先的递归版本来实现这个算法。

你可能感兴趣的:(图的遍历算法分析及应用(3)--拓扑排序)