拓扑排序
工程是否顺序进行,流程是否合理,采用AOV网来表示,顶点用来表示工程(活动),弧表示工程间的顺序关系。如a有一个指向b的弧,意味着a结束了b才能开始(a为弧尾,b为弧头)
算法思路:1,在有向图中找到无前驱(入度为0)的结点V,输出。2,删除V及以V为弧尾的弧。3,重复1,2,输出全部结点/或者网中没有无前驱的点(没有入度为0的点,即存在环)
拓扑排序采用邻接表较方便实现,下面给出以邻接表存储图的算法:
void topoSort(aGraph& G)
{
int* inDegree = new int[G.vexnum];
int i, j;
arcNode* temp;
for (i = 0; i < G.vexnum; i++)
inDegree[i] = 0;
for (i = 0; i < G.vexnum; i++)
for (temp = G.vertices[i].firstArc; temp; temp = temp->nextArc)
inDegree[temp->adjvex]++;//保存所有结点的入度
int* stack = new int[G.vexnum];//用栈来保存入度为0的点,当然,用别的存储结构也行
int top = -1;
for (i = 0; i < G.vexnum;i++)
if (inDegree[i] == 0)
stack[++top] = i;
int count = 0;//判断是否有环
while (top != -1)
{
j = stack[top--];
std::cout << G.vertices[j].data << ' ';
++count;
for (temp = G.vertices[j].firstArc; temp; temp = temp->nextArc)
{
inDegree[temp->adjvex]--;
if (inDegree[temp->adjvex]==0)
stack[++top] = temp->adjvex;
}
}
if (count != G.vexnum)
std::cout << "存在环!" << '\n';
}
完整示例
输入为下面的有向图,求它的拓扑排序:
#include<iostream>
#define maxSize 7//顶点数目
#define MAX 11//边的个数
//邻接表
typedef struct arcNode
{
int adjvex;//与该边所连顶点的序号
//int weight;//边上的权值
struct arcNode* nextArc;
}arcNode;//边表结点
typedef struct
{
char data;//顶点中存储的数据
arcNode* firstArc;
}adjList;//顶点
typedef struct{
int vexnum, arcnum;
adjList vertices[maxSize];
}aGraph;
void topoSort(aGraph& G);//拓扑排序
int main()
{
using namespace std;
aGraph G;//邻接矩阵存储图并进行初始化
G.vexnum = maxSize;
G.arcnum = MAX;
char vexData[maxSize] = { 'a', 'b', 'c', 'd', 'e','f','g' };//顶点信息
int arcData[MAX][2] = { { 0, 2 }, { 0, 3 }, { 0, 4 }, { 1, 4 }, { 1, 3 }, { 2, 5 }, { 4, 3 },
{ 3, 6 },{ 3, 5 }, { 4, 6 }, { 4, 5 } };//连接的边
int i, j;
for (i = 0; i < G.vexnum; ++i)
{
G.vertices[i].data = vexData[i];
G.vertices[i].firstArc = NULL;
for (j = 0; j < G.arcnum;++j)
if (i == arcData[j][0])
{
arcNode* temp = new arcNode;
temp->adjvex = arcData[j][1];
temp->nextArc = G.vertices[i].firstArc;
G.vertices[i].firstArc = temp;//通过头插法构造
}
}
//邻接表初始化完毕
cout << "拓扑排序: ";
topoSort(G);
cout << endl;
//释放空间(类似析构函数)
arcNode* temp=NULL,* tt=NULL;
for (i = 0; i < G.vexnum; i++)
{
if (G.vertices[i].firstArc)
{
temp = G.vertices[i].firstArc;
while (temp)
{
tt = temp->nextArc;
delete temp;
temp = tt;
}
}
}
return 0;
}
void topoSort(aGraph& G)
{
int* inDegree = new int[G.vexnum];
int i, j;
arcNode* temp;
for (i = 0; i < G.vexnum; i++)
inDegree[i] = 0;
for (i = 0; i < G.vexnum; i++)
for (temp = G.vertices[i].firstArc; temp; temp = temp->nextArc)
inDegree[temp->adjvex]++;//保存所有结点的入度
int* stack = new int[G.vexnum];//用栈来保存入度为0的点,当然,用别的存储结构也行
int top = -1;
for (i = 0; i < G.vexnum;i++)
if (inDegree[i] == 0)
stack[++top] = i;
int count = 0;//判断是否有环
while (top != -1)
{
j = stack[top--];
std::cout << G.vertices[j].data << ' ';
++count;
for (temp = G.vertices[j].firstArc; temp; temp = temp->nextArc)
{
inDegree[temp->adjvex]--;
if (inDegree[temp->adjvex]==0)
stack[++top] = temp->adjvex;
}
}
if (count != G.vexnum)
std::cout << "存在环!" << '\n';
}
输出结果为: