看了拓扑排序 这里走一遍拓扑排序的代码以及运算结果 相关的代码解释 已经在程序中标明了!
#include <iostream>
#include <stack>
using namespace std;
const int MAX_VERTEX_NUM = 30;//最大结点数
stack<int> s;//定义栈 存储度为0的顶点
typedef struct ArcNode//边表结点
{
int adjvex;//邻接结点 存储该顶点对应的下标
struct ArcNode* next;//链域 指向下一个邻接点
ArcNode(){ next = 0; }
}ArcNode;
typedef struct VNode//顶点表结点
{
int data;//顶点域 存储顶点信息
ArcNode *first;//边表头指针
VNode(){ first = 0; }
}VNode, AdjList[MAX_VERTEX_NUM];
typedef struct ALGraph
{
AdjList vertices;//顶点数组
int vexnum, arcnum;
}ALGraph;
//这里是全局变量 所以在main函数中 直接使用了g
ALGraph g;//用邻接矩阵表示的图
int indegree[MAX_VERTEX_NUM];//定义一个度的数组 用如存储顶点的入度信息
bool TopologicalSort(ALGraph G, int *indegree)
{
int i, k;
//入度为0入栈
for (i = 1; i <= G.vexnum; ++i)
{
if (!indegree[i])
s.push(i);//将入度为0的顶点放入到栈中
}
int count = 0;
ArcNode *p;
while (!s.empty())//如果栈不为空 那么执行出栈操作
{
i = s.top();
s.pop();
cout << G.vertices[i].data << "-->";//输出该顶点的信息
count++;//统计顶点的数目
for (p = G.vertices[i].first; p; p = p->next)//输出该顶点的所有的边表结点
{
k = p->adjvex;
indegree[k]--;//入度递减
if (!indegree[k])//如果这个点的入度为0了 那么也将这个顶点放入到栈中去
s.push(k);
}
}
if (count < G.vexnum)
{
return false;
}
return true;//count数与顶点数目相等时 表明这是一个五环AOV网
}
int main()
{
cout << "请输入结点数和边数:";
cin >> g.vexnum >> g.arcnum;//vexnum是顶点数 arcnum是边数
//这里设置为第i个结点的data值为i i从一开始
for (int i = 1; i <= g.vexnum; ++i)
g.vertices[i].data = i;//为顶点数组中的每个顶点输入信息
int b, e;
ArcNode *p;
cout << "分别输入边的顶点对 例如3 5" << endl;
for (int i = 1; i <= g.arcnum; ++i)
{
cout << "第" << i << "条边";
cin >> b >> e;//边的两个顶点
p = new ArcNode();
p->adjvex = e;//将e赋值给边表结点的数据域
//采用头插的方式将该边插入到边表中去
p->next = g.vertices[b].first;
g.vertices[b].first = p;
indegree[e]++;//然后将这条边增加到顶点e的入度中去
cout << endl;
}
//采用拓扑排序函数 如果没有环 那么则可以成功输入 如果有环 报错
if (TopologicalSort(g, indegree))
cout << "拓扑排序成功!" << endl;
else
cout << "该有向图有环" << endl;
return 0;
}
下面是运行的结果 可以参考一下
请输入结点数和边数:12 16
分别输入边的顶点对 例如3 5
第1条边1 2
第2条边1 3
第3条边2 3
第4条边1 4
第5条边3 5
第6条边4 5
第7条边11 6
第8条边5 7
第9条边3 7
第10条边3 8
第11条边6 8
第12条边9 10
第13条边9 11
第14条边9 12
第15条边10 12
第16条边1 12
9-->10-->11-->6-->1-->2-->3-->8-->4-->5-->7-->12-->拓扑排序成功!