拓扑排序(TopologicalSort)算法

时间:2023-03-09 07:20:46
拓扑排序(TopologicalSort)算法

拓扑排序(TopologicalSort)算法

拓扑排序算法应用:

  有些事情做都需要按照流程的去做,比如你准备约你小女友去影院看速度与激情7大片,首先你想的是我怎么到达影院,然后达到影院,你可以先买票,或者等小女友来了一起买票,然后一起进电影大厅.....然后说说甜言蜜语时机成熟了有可以做下一步了;作为顶点:自己的位置,影院位置,小女友到达影院,买票,进大厅,作为顶点,比如都到达了影院买好票才可以一起进入,就是当一个顶点都被满足时才可以该顶点才可以做动作执行下一步。这是我自己的理解方式,你要还不理的话可能是我说的不够好!

 /*
拓扑排序基本思想:
1.查找原始图中入度为0的顶点都入栈。
2.所有顶点都入栈后,在一个顶点一个顶点的出栈。
3.出栈一个顶点若是有邻接表的话,该邻接表的顶点入度-1 = 0的话,
该邻接表的顶点入栈,然后一直循环。。。
*/ #include <stdio.h>
#include <malloc.h>
#include <stdlib.h> #define MAXVEX 14//最大顶点数
#define MAXEDGE 20//最大边数 /* 邻接矩阵结构 */
typedef struct
{
int vexs[MAXVEX];//顶点下标
int arc[MAXVEX][MAXVEX];//矩阵
int numVertexes, numEdges;//当前图中的顶点数和边数 }MGraph; /* 邻接表结构 */
typedef struct EdgeNode
{//边表结点
int adjlist;//邻接点域,存储该顶点下标
int weigth;//用于存储权值,对于无网图可以忽略
struct EdgeNode *next;//链域,指向下一个邻接点域 }EdgeNode; typedef struct
{//顶点表结点
int in;//顶点入度
int data;//顶点域,存储顶点信息
EdgeNode *firstedge;//边表头指针 }VertexNode, AdjList[MAXVEX]; typedef struct
{
AdjList adjlist;//顶点向量
int numVertexes, numEdges;//当前图中顶点数和边数 }graphAdjList,*GraphAdjList; /**********************************************************/ /* 构件图 */
void CreateMGraph(MGraph *G)
{
int i, j; // printf("请输入顶点数和边数:\n");
G->numVertexes = MAXVEX;
G->numEdges = MAXEDGE; //初始化顶点下标
for(i=; i<G->numVertexes; i++)
G->vexs[i] = i; //初始化矩阵
for(i=; i<G->numVertexes; i++)
for(j=; j<G->numVertexes; j++)
G->arc[i][j] = ; //内置输入
G->arc[][] = ;
G->arc[][] = ;
G->arc[][] = ;
G->arc[][] = ;
G->arc[][] = ;
G->arc[][] = ;
G->arc[][] = ;
G->arc[][] = ;
G->arc[][] = ;
G->arc[][] = ;
G->arc[][] = ;
G->arc[][] = ;
G->arc[][] = ;
G->arc[][] = ;
G->arc[][] = ;
G->arc[][] = ;
G->arc[][] = ;
G->arc[][] = ;
G->arc[][]= ;
G->arc[][] = ; return ;
} /* 采用矩阵-构建邻接表 */
void CreateALGraph(MGraph G, GraphAdjList *GL)
{
int i, j;
EdgeNode *e; *GL = (GraphAdjList)malloc(sizeof(graphAdjList));
(*GL)->numVertexes = G.numVertexes;
(*GL)->numEdges = G.numEdges; for(i=; i<G.numVertexes; i++)
{//初始化邻接表
(*GL)->adjlist[i].in = ;
(*GL)->adjlist[i].data = G.vexs[i];
(*GL)->adjlist[i].firstedge = NULL;
} //建立邻接表
for(i=; i<G.numVertexes; i++)
for(j=; j<G.numVertexes; j++)
if(G.arc[i][j] == )
{//若存在关系
e = (EdgeNode *)malloc(sizeof(EdgeNode));
e->adjlist = j;
e->next = (*GL)->adjlist[i].firstedge;
(*GL)->adjlist[i].firstedge = e;//头插法
(*GL)->adjlist[j].in ++;//该顶点入度+1
} return ;
} int TopologicalSort(GraphAdjList GL)
{/* 拓扑排序 */
EdgeNode *e;
int i, k, gettop;
int top = ;//指向栈顶
int count = ;//记数
int *stack;//建立一个栈
stack = (int *)malloc(GL->numVertexes * sizeof(int)); //把没有入度的顶点入栈
for(i=; i<GL->numVertexes; i++)
if( == GL->adjlist[i].in)
stack[++top] = i; while(top != )
{//若栈中有元素存在
gettop = stack[top--];//栈顶顶点的下表给gettop,然后top-1
printf("%d->", GL->adjlist[gettop].data);//打印出栈顶点信息
count++; for(e=GL->adjlist[gettop].firstedge; e; e=e->next)
{//判断出栈的顶点是否有出度
k = e->adjlist;//有则邻接点域顶点下标赋值K
if(!(--GL->adjlist[k].in))//该邻接点域的顶点入度-1(因为出栈的顶点已经指向该顶点,所以-1)后没有入度为0的话
stack[++top] = k;//则该顶点入栈
}
}
printf("\n");
if(count < GL->numVertexes)
exit(-);//若小于顶点数,证明存在环
else
return ;
} int main(void)
{
MGraph G;
GraphAdjList GL;
CreateMGraph(&G);//构件图
CreateALGraph(G, &GL);//构建邻接表
TopologicalSort(GL);//拓扑排序
system("PAUSE"); return ;
} /*
在vc++6.0运行结果:
3->1->2->6->0->4->5->8->7->12->9->10->13->11->
请按任意键继续. . .
*/