Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2892222
  • 博文数量: 674
  • 博客积分: 17881
  • 博客等级: 上将
  • 技术积分: 4849
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-17 10:15
文章分类

全部博文(674)

文章存档

2013年(34)

2012年(146)

2011年(197)

2010年(297)

分类: LINUX

2011-11-11 21:51:32

拓扑排序方法:

①从有向图中选一个没有前驱的顶点且输出之。

②从有向图中删除该顶点和所有以他为尾的弧。

重复上述两步,直至所有顶点已输出,或当期图中不存在无前驱的顶点为止。后一种情况说明有向图中有环!

 

1. 采用邻接矩阵存储

  1. //图的邻接矩阵存储表示   
  2. #define INFINITY INT_MAX   
  3. #define MAX_VERTEX_NUM 20   
  4. typedef enum {DG, DN, UDG, UDN} GraphKind; //{有向图,有向网,无向图,无向网}   
  5. typedef enum {OK, ERROR} Status;  
  6. typedef struct ArcCell{  
  7.     int adj;        //顶点关系类型。对于无权图,用0或1表示相邻否。对于有权图,则为权值类型。   
  8.     string info;    //该弧所携带的信息   
  9. }ArcCell, AdjMatrix;  
  10. typedef struct {  
  11.     int vexs[MAX_VERTEX_NUM];   //顶点向量   
  12.     AdjMatrix arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];             //邻接矩阵   
  13.     int vexnum, arcnum;         //图的当前顶点数和弧数   
  14.     GraphKind kind;             //图的种类标志   
  15. }MGraph;  
//图的邻接矩阵存储表示 #define INFINITY INT_MAX #define MAX_VERTEX_NUM 20 typedef enum {DG, DN, UDG, UDN} GraphKind; //{有向图,有向网,无向图,无向网} typedef enum {OK, ERROR} Status; typedef struct ArcCell{ int adj; //顶点关系类型。对于无权图,用0或1表示相邻否。对于有权图,则为权值类型。 string info; //该弧所携带的信息 }ArcCell, AdjMatrix; typedef struct { int vexs[MAX_VERTEX_NUM]; //顶点向量 AdjMatrix arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //邻接矩阵 int vexnum, arcnum; //图的当前顶点数和弧数 GraphKind kind; //图的种类标志 }MGraph; 

 

2. 用函数构造一个有向图

  1. void CreateDGTest(MGraph &G)  
  2. {   //构造一个有向图   
  3.     int i,j;  
  4.     G.kind = DN;  
  5.     //数组a[11][2]用来存储有向边   
  6.     int a[13][2] = { {0,1}, {0,2}, {0,3}, {1,4}, {2,4}, {3,5}, {4,6}, {4,7}, {5,7}, {6,8}, {7,8}, {2,1}, {7,6}};  
  7.     G.vexnum = 9;  
  8.     G.arcnum = 13;  
  9.     for(i=0; i
  10.         G.vexs[i] = i;  
  11.     for(i=0; i
  12.         for(j=0; j
  13.         {  
  14.             G.arcs[i][j].adj = 0;  
  15.             G.arcs[i][j].info = "";  
  16.         };  
  17.     for(i=0; i
  18.         G.arcs[a[i][0]][a[i][1]].adj = 1;  
  19. }  
void CreateDGTest(MGraph &G) { //构造一个有向图 int i,j; G.kind = DN; //数组a[11][2]用来存储有向边 int a[13][2] = { {0,1}, {0,2}, {0,3}, {1,4}, {2,4}, {3,5}, {4,6}, {4,7}, {5,7}, {6,8}, {7,8}, {2,1}, {7,6}}; G.vexnum = 9; G.arcnum = 13; for(i=0; i

 

3. 拓扑排序函数

  1. Status TopologicalSortT(MGraph G)  
  2. {   //有向图采用邻接矩阵存储   
  3.     //若G无回路,则输出G的顶点的一个拓扑序列,并返回OK,否则ERROR   
  4.     int i,j;  
  5.     int indegree[MAX_VERTEX_NUM];       //存储各顶点入度   
  6.     int topo[MAX_VERTEX_NUM];           //存储顶点拓扑序列         
  7.     int num=0;                          //计数已经输出/存储的顶点   
  8.     int sp=-1;                          //存储下一步需要删除的边的尾的前一点   
  9.     for(i=0; i
  10.     {   //计算各顶点入度   
  11.         indegree[i] = 0;  
  12.         for(j=0; j
  13.             if(G.arcs[j][i].adj != 0 && i!=j)  
  14.                 indegree[i]++;  
  15.         if(indegree[i]==0)  
  16.         {  
  17.             topo[num] = i;  
  18.             num++;  
  19.         }  
  20.     }  
  21.     while(sp < num)  
  22.     {   //sp  
  23.         sp++;  
  24.         for(i=0; i
  25.             if(G.arcs[sp][i].adj != 0)  
  26.             {  
  27.                 indegree[i]--;  
  28.                 if(indegree[i] == 0)  
  29.                 {  
  30.                     topo[num] = i;  
  31.                     num++;  
  32.                 }  
  33.             }  
  34.     };  
  35.     if(num
  36.         return ERROR;  
  37.     cout<<"拓扑序列如下:";  
  38.     for(i=0; i
  39.         cout<
  40.     cout<
  41.     return OK;  
  42. }  
Status TopologicalSortT(MGraph G) { //有向图采用邻接矩阵存储 //若G无回路,则输出G的顶点的一个拓扑序列,并返回OK,否则ERROR int i,j; int indegree[MAX_VERTEX_NUM]; //存储各顶点入度 int topo[MAX_VERTEX_NUM]; //存储顶点拓扑序列 int num=0; //计数已经输出/存储的顶点 int sp=-1; //存储下一步需要删除的边的尾的前一点 for(i=0; i

 

4. 拓扑排序函数-利用堆栈

  1. Status TopologicalSortStack(MGraph G)  
  2. {   //有向图采用邻接矩阵存储   
  3.     //借助堆栈实现   
  4.     //若G无回路,则输出G的顶点的一个拓扑序列,并返回OK,否则ERROR   
  5.     int i,j;  
  6.     int indegree[MAX_VERTEX_NUM];       //存储各顶点入度      
  7.     int num=0;                          //计数已经输出/存储的顶点   
  8.     LinkStack S;  
  9.     InitStack(S);  
  10.     for(i=0; i
  11.     {   //计算各顶点入度   
  12.         indegree[i] = 0;  
  13.         for(j=0; j
  14.             if(G.arcs[j][i].adj != 0 && i!=j)  
  15.                 indegree[i]++;  
  16.         if(indegree[i]==0)  //零入度顶点进栈   
  17.             Push(S,i);  
  18.     }  
  19.     while(!StackEmpty(S))  
  20.     {   //栈非空   
  21.         Pop(S, i);  
  22.         cout<
  23.         ++num;      //对输出顶点计数   
  24.         for(j=0; j
  25.             if(G.arcs[i][j].adj != 0)   //对顶点i的每个邻接点入度减1   
  26.             {  
  27.                 indegree[j]--;  
  28.                 if(indegree[j] == 0)    //若入度减为0,则进栈   
  29.                     Push(S, j);  
  30.             }  
  31.     };  
  32.     if(num//该图有有向回路   
  33.         return ERROR;  
  34.     return OK;  
  35. }  
Status TopologicalSortStack(MGraph G) { //有向图采用邻接矩阵存储 //借助堆栈实现 //若G无回路,则输出G的顶点的一个拓扑序列,并返回OK,否则ERROR int i,j; int indegree[MAX_VERTEX_NUM]; //存储各顶点入度 int num=0; //计数已经输出/存储的顶点 LinkStack S; InitStack(S); for(i=0; i

 

5. 测试用主函数

  1. int main()  
  2. {  
  3.     MGraph gra3;  
  4.     CreateDGTest(gra3);  
  5.     if(TopologicalSortT(gra3) != OK)  
  6.         cout<<"该有向图存在环!"<
  7.     return 0;  
  8. }  

http://blog.csdn.net/hustspy1990/article/details/6044098

阅读(1533) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~