拓扑排序是对有向无圈图的顶点的一种排序,它使得如果存在一条从vi到vj的路径,那么在排序中vj出现在vi的后面。
一种简单的做法是先找出一个没有入边的顶点,然后显示出该顶点,并将它和它的边一起删除。如果每次都通过遍历所有顶点来找的话,那么运行时间将是O(|V|^2),其中|V|为顶点数。
我们可以将所有的入度为0的顶点放在一个序列中,每次出列一个顶点,并将删除边后入度为0的顶点进队列,这样避免了每次都要遍历的麻烦,如果使用邻接表实现的话,运行时间为O(|V|+|E|)。
下面为一个例子:
文本第一行为顶点数,第二行为边数,下面为每个顶点的边连接情况,如第二行第一列的1表示v1到v2有一条边。
// Topsort.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include
#include
#include
#include
using namespace std;
#define MAXV 7
//*******表结构体**************//
typedef struct
{
int no;
char* info;
}vertex;
typedef struct
{
int edges[MAXV][MAXV] ;
int n, e;
vertex vexs[MAXV];
}MGraph;
//*****************************//
//**********队列结构体**********//
typedef struct
{
int data[MAXV];
int front, rear;
}SqQueue;
//*****************************//
void InitQueue(SqQueue *&q)//初始化队列
{
q = (SqQueue *)malloc(sizeof(SqQueue));
q->front = q->rear = 0;
}
void ClearQueue(SqQueue *&q)//释放队列
{
free(q);
}
int enQueue(SqQueue *&q, int e)//入队列
{
if ((q->rear + 1) % MAXV == q->front)
return 0;
q->rear = (q->rear+1) % MAXV;
q->data[q->rear] = e;
return 1;
}
int deQueue(SqQueue *&q, int &e)//出队列
{
if (q->front == q->rear)
return 0;
q->front = (q->front + 1) % MAXV;
e = q->data[q->front];
return 1;
}
int QueueEmpty(SqQueue *q)//判断队列是否为空
{
return (q->front == q->rear);
}
void CalIndegree(MGraph g, int Indegree[])//计算入度
{
int i,j;
for (i = 0; i < g.n; i++)
{
Indegree[i] = 0;
for (j = 0; j < g.n; j++)
{
if (g.edges[i][j] != 0)
Indegree[i]++;
}
}
}
void TopSort(MGraph g,int Topnum[])//拓扑排序
{
SqQueue *q;
q = (SqQueue *)malloc(sizeof(q));
int counter = 0;
InitQueue(q);
int i,j,k;
int Indegree[MAXV];
CalIndegree(g, Indegree);
for (i = 0; i < g.n; i++)
{
if (Indegree[i] == 0)
enQueue(q, i);
}
printf("拓扑排序序列:");
while (!QueueEmpty(q))
{
deQueue(q, i);
printf("%s ", g.vexs[i].info);
Topnum[i] = ++counter;
for (j = 0; j < g.n; j++)
{
if (g.edges[j][i] == 1 && --Indegree[j] == 0)
enQueue(q, j);
}
}
printf("\n");
if (counter != g.n)
printf("Graph has a cycle");
}
int _tmain(int argc, _TCHAR* argv[])
{
MGraph g;
g.vexs[0].no = 1;
g.vexs[0].info = "v1";
g.vexs[1].no = 2;
g.vexs[1].info = "v2";
g.vexs[2].no = 3;
g.vexs[2].info = "v3";
g.vexs[3].no = 4;
g.vexs[3].info = "v4";
g.vexs[4].no = 5;
g.vexs[4].info = "v5";
g.vexs[5].no = 6;
g.vexs[5].info = "v6";
g.vexs[6].no = 7;
g.vexs[6].info = "v7";
int i, j;
int a=0;
FILE *op;
errno_t err=fopen_s(&op, "edges.txt", "r");
if (err==0)
{
fscanf_s(op,"%d",&g.n,sizeof(int));
fscanf_s(op, "\n");
fscanf_s(op, "%d", &g.e, sizeof(int));
fscanf_s(op, "\n");
g.n = 7;
for (i = 0; i < g.n; i++)
{
for (j = 0; j < g.n; j++)
fscanf_s(op, "%d", &g.edges[i][j], sizeof(int));
fscanf_s(op, "\n");
}
}
else
printf("文件打开出错!\n");
int Indegree[MAXV];
CalIndegree(g, Indegree);
int Topnum[MAXV];
TopSort(g, Topnum);
return 0;
}