思想
1.先求的图中每个顶点的入度,将入度为0的顶点加入栈或者队列 F;
2.从F中取出一个顶点,输出,count++,并删除它的出边,将它邻接顶点的入度-1,并将修改后入度为0的顶点加入F;
3.重复第二步直至F为空,若count等于图的总顶点数,说明图中无环。
代码
//输入示例
// 6 7 0 1 2 3 4 5 0 1 1 0 2 3 0 4 3 1 3 5 2 3 1 3 5 4 3 4 3
#include<iostream>
#include <stack>
using namespace std;
#define MAXVEX 100
//拓扑排序用到的图与普通图结构不同,这里是有向图,且要有存储结点入度数的变量
typedef struct EdgeNode //出边表
{
int adjvex; //出边顶点
int weight; //权重
struct EdgeNode* next;
}EdgeNode;
typedef struct VertexNode //顶点表
{
int in = 0; //入度
int data; //值
EdgeNode* firstedge; //顶点出边
}VertexNode,Adjlist[MAXVEX];
typedef struct //有向图
{
Adjlist adjlist; //顶点序列
int numVex, numEdge;
}graphAdjlist,*GraphAdjlist;
void CreatGraph(graphAdjlist &G)
{
int f, t, w;
cout << "输入顶点数,边数"<< endl;
cin >> G.numVex >> G.numEdge;
cout << "输入各顶点值" << endl;
for (int i = 0; i < G.numVex; i++)
{
G.adjlist[i].in = 0;
cin >> G.adjlist[i].data;
G.adjlist[i].firstedge = nullptr;
}
cout << "输入各边,from to weight" << endl;
for (int i = 0; i < G.numEdge; i++) //输入边
{
cin >> f >> t >> w;
EdgeNode* p; //头插法
p = new EdgeNode();
p->adjvex = t;
p->weight = w;
p->next = G.adjlist[f].firstedge;
G.adjlist[f].firstedge = p;
G.adjlist[t].in++;
}
cout << "成功建立图如下:" << endl;
for (int i = 0; i < G.numVex;i++)
{
EdgeNode* q;
q = new EdgeNode();
cout << G.adjlist[i].data << endl;
q = G.adjlist[i].firstedge;
while (q != NULL)
{
cout << q->adjvex << " " << q->weight << " ";
q = q->next;
}
cout << endl;
}
}
void TopuSort(graphAdjlist G)
{
stack<int> inVex;
int top;
int count=0;
int k;
EdgeNode *e;
for (int i = 0; i < G.numVex; i++) //所有入度为0的点入栈
if (G.adjlist[i].in == 0)
inVex.push(i);
while (!inVex.empty()) //栈不为空则
{
top = inVex.top(); //弹出栈顶
inVex.pop();
cout << G.adjlist[top].data << " "; //输出栈顶
count++; //记录已生成序列总顶点数
//对弹出顶点遍历所有邻接点,入度-1,若-1后入度为0则入栈
for (e = G.adjlist[top].firstedge;e!=NULL; e = e->next)
{
k = e->adjvex;
if ((--G.adjlist[k].in)==0)
{
inVex.push(k);
}
}
}
if (count < G.numVex) //拓扑序列数小于顶点总数则说明有环
cout << endl << "有环";
else
cout << endl << "无环";
}
int main()
{
graphAdjlist G;
CreatGraph(G);
TopuSort(G);
return 0;
}