拓扑排序_基于邻接矩阵

人们用一种有向图来表示这些工程、计划等,在这种有向图中,顶点表示活动,有向边表示活动的优先关系,这种用顶点表示活动,用弧来表示活动间的优先关系的有向图叫做顶点表示活动的网络(Actire On Vertices)简称为AOV网。在AOV网中不应该出现有向环。 
通常,在AOV网中,将所有活动排列成一个拓扑序列的过程叫做拓扑排序(Topological Sort)。 、、

从有向图中选择一个没有前驱(即入度为0)的顶点并且输出它。
//算法描述
//  0度结点的权为0
//  核心:假设有a->b(b的权=b的权+a的权+1) 
//  具体实现有:假设有 b->c;b->d;b->e;结点cde进入队列
// 权越小排序越靠前
//

//在编写的代码的过程中,犯了个大错误
//void shenqing(int **&T,int* &dui);//申请动态空间,错误:没有使用引用;导致申请的空间无效
测试数据
6 8

0 1
0 2
0 3
2 4
2 1
3 4
5 3
5 4


#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;  

  int v;//////点数目  
  int edge;///边数目  
  int dui_front=0;//队头
  int dui_rear=0;//队尾//////头有数据,尾无数据

int** draw();//绘图,有向无环图
void shenqing(int **&T,int* &dui);//申请动态空间
void tuopusort(int** a,int** T,int* dui);//拓扑排序
void  SelectSort(int **arr,int length);

int main(int argc, char const *argv[])  
{  
  
  int**a=draw();//图
  int **T;//存放点以及其对应的权,T是n行2列的数组,它的第二列放的权
  int* dui;//队列
  shenqing(T,dui);
  tuopusort(a,T,dui);
  SelectSort(T,v);

  for (int i = 0; i < v; ++i)
  {
    cout<<T[i][0]<<"  "<<T[i][1]<<endl; 
  }
//------------------------------------------------------------------------//  
//释放空间
  delete []a;
  delete []T;
  delete []dui;
  return 0;  
}  


int** draw()//绘图  
{  
  int i,j;  
  cin>>v>>edge;///输入点数目和边数目 
  int **a=new int*[v];
  for ( i = 0; i < v; ++i)  
    a[i]=new int[v];  

  for ( i = 0; i < v; ++i)  
    for ( j = 0; j < v; ++j)  
      a[i][j]=0;  
  
  int spot1,spot2;  
  for ( i = 0; i < edge; ++i)  
  {  
    cin>>spot1>>spot2;  
    a[spot1][spot2]=1;   
  }  
///-------------------------------------------------------------///  
     cout<<"\n";  
    for ( i = 0; i < v; ++i)
    {  
      for ( j = 0; j < v; ++j)
      {
        cout<<a[i][j]<<" "; 
        } 
    cout<<"\n";  
    }  
    cout<<"\n";  
  return a;  
}  
void shenqing(int **&T,int* &dui)//引用
{
    int i;
  T=new int*[v];
  for ( i = 0; i < v; ++i)  
    T[i]=new int[2];  

  for ( i = 0; i < v; ++i)
  {
      T[i][0]=i;  T[i][1]=0;  
  }

  dui=new int[v];
}
void tuopusort(int** a,int** T,int* dui)
{
  int i,j,temp;
//----------------------------------------------------//
 ////获取0入度结点,放入队列中 
  int panduan=0;
    for ( i = 0; i < v; ++i)
       {
          for ( j = 0; j < v; ++j)//计算列
          {
            if(a[j][i]==1)panduan=1;
          }
          if (panduan==0)//0入度的结点
          {
            temp=dui_rear++ % v;
            dui[temp]=i;
          }
          panduan=0;
       }
//----------------------------------------------------//
  if (dui_front==dui_rear)///无0入度的结点,及有环
  {
    cout<<"有环";
    exit(1);
  }
//----------------------------------------------------//
    int tempdui;
    while(true)
    {
         tempdui = dui[dui_front++ % v];
         for ( i = 0; i < v; ++i)
         {
             if (a[tempdui][i]==1)
             {
              T[i][1] += T[tempdui][1] +1;

              for ( j = dui_front; j < dui_rear; ++j)
                 if (i==j)continue;//已经存在结点i了,不能再次加进去了

              dui[dui_rear++ % v]=i;
             }
           }
      if (dui_front==dui_rear)
         break;//处理完毕
    }
}
void  SelectSort(int **arr,int length){
  int min,temp,temp2;
  for(int i=0;i<length-1;i++)
  {
    min=i;
      for(int j=i+1;j<length;j++)
      {
        if(arr[min][1]>arr[j][1])
          min=j;  
      }
      if(i<min)/////////下面的三条语句实现交换
      {
        temp=arr[i][0];          temp2=arr[i][1];
        arr[i][0]=arr[min][0];   arr[i][1]=arr[min][1];
        arr[min][0]=temp;        arr[min][1]=temp2;
      }
  }
}

    原文作者:拓扑排序
    原文地址: https://blog.csdn.net/h1023417614/article/details/18769529
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞