拓扑排序

时间复杂度 O(m+n)
检查有向图中是否存在回路的方法之一就是拓扑排序
这里记载两种拓扑排序的方法
方法一:堆栈或队列法
 
严蔚敏所著的数据结构书对这段描述存在错误
正确的描述应为:
  1. 在图中选取没有入度的点入栈或入队
  2. 出栈或出队,将其出度点的入度减一,如果入度数降为0,入栈或入队
反复进行2直至栈或队为空,如果出栈或出队总数等于点的总数,则为无环图,小于为有环图,不可能存在大于。

代码实现
//使用邻接链表
struct chududian
{
    int n;
    struct chududian *next;
};
struct node
{
    int rudu;
    struct chududian *next;
}G[N];
void tuopu()
{
    int stacknum=0;
    int queuenum=0;
    struct chududian *p;
    for(int i=0;i<N;i++)
    {
        if(G[i].rudu==0)
           {
            STACK[stacknum]=i;
            stacknum++;
            }
    }
    while(stacknum)
    {
        int n;
        stacknum--;
        n=STACK[stacknum];
        p=G[n].next;
        QUEUE[queuenum]=n;
        queuenum++;
        while(p!=NULL)
        {
            G[p->n].rudu--;
            if(G[p->n].rudu==0)
            {
                STACK[stacknum]=p->n;
                stacknum++;
            }
            p=p->next;
        }
    }
    //我们把出栈的放入队中,判断队的长度即可知是否有环
    if(queuenum<N)
        cout<<"该图有环"<<"  ";
    cout<<"拓扑排序为:";
    if(queuenum==0)
        cout<<"无"<<"\n";
    else
        {
        for(int i=0;i<queuenum;i++)
        cout<<QUEUE[i]<<" ";
        cout<<"\n";
        }
}
方法二:深度优先搜索法

运用深度优先搜索进行拓扑排序,回溯,依次对各点深搜,访问过的跳过,按退出的前后顺序进行记录,先退出的放后面,重复访问不记录,可以通过点是否在递归中判断是否有环(非递归判断是否在栈中)

优点在于不用记录点的入度数


//结构如下,开始时flag1均置false,代表没被访问过,flag2均置false表示没在递归中
struct chududian
{
    int data;
    struct chududian *next;
};
struct node
{
    bool flag1;
     bool flag2;
    struct chududian *next;
}G[N];
int n=N-1;
int que[N];//记录数组
void toupu()
{
    for(int i=0;i<N;i++)
        {
            dfs(i);
        }
    for(int i=0;i<N;i++)
        {
           cout<<que[i]<<"  ";
        }
        cout<<"\n";
}
void dfs(int i)
{
    if(G[i].flag1)
         {
          if(G[i].flag2)
          {
          cout<<"有环";
           system( "pause" );
      exit(0);
          }
          return;
          }
    G[i].flag1=true;//标记为访问过
     G[i].flag2=true;//标记为在递归中
    struct chududian *q;
    q=G[i].next;
    while(q!=NULL)
    {
        dfs(q->data);
        q=q->next;
    }
    que[n]=i;
    n--;
     G[i].flag2=false;//标记为不在递归中

你可能感兴趣的:(拓扑排序)