拓扑排序是,将有向图中每个点按照一定的顺序排列。如果有向边 vi->vj存在,那么vi结点必须出现在vj之前。
算法思想:
(1)首先我们利用邻接表保存图结构。
(2)利用一个数组indegree[]数组来记录每个结点的入度。
(3)将入度为0的点加入到堆栈 stack中。
(4)将结点node出栈,清除node发出每一条边node->to,并将indegree[to]--。
(5)继续寻找入度为0的点,加入栈,直到栈为空。
时间复杂度:O(V+E)
#include <iostream>
#include <stack>
using namespace std;
const int MAXN = 1000;
struct Edge
{
int to;
int value;
int next;
Edge()
{
value = 0;
next = -1;
}
}e[MAXN*2];
int head[MAXN];
int indegree[MAXN];
int edgeNum = 0; //全局唯一标示,边的数目
int v; //结点数目
void addEdge(int from,int to)
{
e[edgeNum].to = to;
e[edgeNum].next = head[from];
head[from] = edgeNum++;
}
bool findZeroIndegree(int& vert)
{
for ( int i = 1; i <= v; i++ )
{
if( indegree[i] == 0 )
{
vert = i;
return true;
}
}
return false;
}
void topSort()
{
stack<int> myStack; //定义堆栈
int node;
if( findZeroIndegree(node) )
{
myStack.push(node);
}
else
{
printf("无法排序!\n");
return ;
}
int count = 0;
while ( !myStack.empty() )
{
count++;
node = myStack.top();
myStack.pop();
indegree[node] = -1; //标记该点已经访问过了
cout << node << endl;
//清除node发出的所有边
for ( int index = head[node]; index != -1; index = e[index].next )
{
int to = e[index].to;
indegree[to]--;
}
if( findZeroIndegree(node) )
myStack.push(node);
}
if( count != v )
cout << "无法排序" << endl;
}
int main()
{
int n; //边数
printf("请输入边的数目:");
scanf("%d%d",&v,&n);
memset(head,-1,sizeof(head));
memset(indegree,0,sizeof(indegree));
int from,to;
for ( int i = 0; i < n; i++ )
{
scanf("%d %d",&from,&to);
addEdge(from,to);
indegree[to]++;
}
topSort();
return 0;
}