拓扑排序

来源:互联网 发布:小心眼表现 知乎 编辑:程序博客网 时间:2024/05/16 05:18
有向图可以拓扑排序的条件是:图中没有环。
 具体方法:
 ⑴ 从图中选择一个入度为0的点加入拓扑序列。
 ⑵ 从图中删除该结点以及它的所有出边(即与之相邻点入度减1)。

 反复执行这两个步骤,直到所有结点都已经进入拓扑序列。

参照严蔚敏的《数据结构(C语言版)》教材,163页有图的邻接表结构定义方法,181-182有课程优先关系的用例和拓扑排序的核心代码。

代码如下:

[cpp] view plaincopy
  1. #include <iostream>  
  2. #include <fstream>  
  3. #include <stack>  
  4. using namespace std;  
  5.   
  6. ifstream fin("in.txt");  
  7. #define MAX_VERTEX_NUM 26  
  8.   
  9. stack<int> s;  
  10.   
  11. typedef struct ArcNode{  
  12.     int adjvex;  
  13.     struct ArcNode *nextarc;  
  14.     ArcNode(){nextarc=0;}  
  15. //  InfoType *info;  
  16. }ArcNode;  
  17.   
  18. typedef struct VNode{  
  19.     int data;  
  20.     ArcNode *firstarc;  
  21.     VNode(){firstarc=0;}  
  22. }VNode,AdjList[MAX_VERTEX_NUM];  
  23.   
  24. typedef struct{  
  25.     AdjList vertices;  
  26.     int vexnum,arcnum;  
  27.     int kind;  
  28. }ALGraph;  
  29.   
  30. bool TopologicalSort(ALGraph G,int *indegree)  
  31. {  
  32.     int i,k;  
  33.     for(i=1;i<G.vexnum+1;i++)  
  34.     {  
  35.         if(!indegree[i]){s.push(i);}  
  36.     }  
  37.     int count=0;  
  38.     ArcNode *p;  
  39.     while(!s.empty())  
  40.     {  
  41.         i = s.top();  
  42.         s.pop();  
  43.         cout<<G.vertices[i].data<<"-->";  
  44.         count++;  
  45.         for(p=G.vertices[i].firstarc;p;p=p->nextarc)  
  46.         {  
  47.             k = p->adjvex;  
  48.             indegree[k]--;  
  49.             if(!indegree[k])s.push(k);  
  50.         }  
  51.     }  
  52.     if(count<G.vexnum) return false;  
  53.     return true;  
  54. }  
  55.   
  56.   
  57. int main()  
  58. {  
  59.     int i;  
  60.     ALGraph g;  
  61.     cout<<"输入节点数和边数: ";  
  62.     fin>>g.vexnum>>g.arcnum;  
  63.     for(i=1;i<g.vexnum+1;i++)  
  64.         g.vertices[i].data = i;  
  65.   
  66.     int b,e;  
  67.     ArcNode *p;  
  68.     int *indegree = new int[g.vexnum+1];      
  69.     //注意 int *a=new int(n);  申请一个整型变量空间,赋初值为n,并定义一个整型指针a指向该地址空间   
  70.     //int *indegree=(int *)malloc(sizeof(int)*(g.vexnum+1));  
  71.     memset(indegree,0,sizeof(int)*(g.vexnum+1));  
  72.     cout<<"逐一输入边的顶点对,形如 3 5 "<<endl;  
  73.     for(i=1;i<g.arcnum+1;i++)  
  74.     {  
  75.         cout<<"第"<<i<<"条边:";  
  76.         fin>>b>>e;  
  77.         p = new ArcNode();  
  78.         p->adjvex = e;  
  79.         p->nextarc = g.vertices[b].firstarc;  
  80.         g.vertices[b].firstarc = p;  
  81.         indegree[e]++;  
  82.         cout<<endl;  
  83.     }  
  84.     if(TopologicalSort(g,indegree))cout<<"正常完成!"<<endl;  
  85.     else cout<<"该有向图有回路!"<<endl;  
  86.     return 0;  
  87. }  

输入文件 in.txt:

12 16
1 2
1 3
2 3
1 4
3 5
4 5
11 6
5 7
3 7
3 8
6 8
9 10
9 11
9 12
10 12
1 12


输出结果:

输入节点数和边数: 逐一输入边的顶点对,形如 3 5
第1条边:
第2条边:
第3条边:
第4条边:
第5条边:
第6条边:
第7条边:
第8条边:
第9条边:
第10条边:
第11条边:
第12条边:
第13条边:
第14条边:
第15条边:
第16条边:
9-->10-->11-->6-->1-->2-->3-->8-->4-->5-->7-->12-->正常完成!
Press any key to continue

0 0
原创粉丝点击