拓扑排序
定义:对有向无环图(DAG)进行拓扑排序,是将G中所有顶点排成一个线性序列,并且有先后关系次序,使得任意一对顶点u和v,即<u,v>,u都出现在v之前。
实现方法
1.从DAG中寻找入度为0的顶点,并将它输入,作为已经排序出来的顶点.
2.从图中删除第一步中的顶点,并与之相邻的边都做相应的调整,即入度减1(若存在相邻关系).
3.重复第一和第二步,直至所有顶点均输出.
拓扑排序代码:
#include<iostream>
#include<stack>
using namespace std;
struct DAG //有向无环图中的边
{
char w1,w2;
int weight;
};
#define M 100
int e; //M最大顶点数,e边数
char data[M]; //n个顶点 代表每个顶点的字符
int Edge[M][M]; //顶点对应的权值,若存在,则假设不权值为0
int Degree[M]; //存储每个节点的入度
int visited[M];
//初始化图
void InitGraph(int t)
{
int i,j;
for(i=0;i<t;++i)
{
data[i]='a'+i;
visited[i]=0;
for(j=0;j<t;++j)
Edge[i][j]=0;
}
}
void MakeGraph(DAG d[],int len)
{
int j,i=0;
while(i<len)
{
Edge[d[i].w1-'a'][d[i].w2-'a']=d[i].weight;
++i;
}
}
void TopSort(int t)
{
stack<int> s;
//统计结点的入度
int i,j,count=0,d,result;
for(j=0;j<t;++j)
{
d=0;
for(i=0;i<t;++i)
{
if(Edge[i][j]!=0) d++;
}
Degree[j]=d; //j的入度为d
if(Degree[j]==0)
s.push(j);
}
while(count<t) //count为已经排序出来的顶点个数
{
if(!s.size()) break; //栈中已没有入度为0的顶点
result=s.top();
s.pop(); //压出入度为0的顶点
count++;
visited[result]=1; //标记该节点已被访问过
cout<<data[result]<<" ";
for(i=0;i<t;++i)
{
if(Edge[result][i]!=0) { Degree[i]--;Edge[result][i]=0;}
if(Degree[i]==0&&!visited[i]) s.push(i);
}
}
if(count!=t) cout<<"图中存在环,该排序不是拓扑排序"<<endl;
}
int main()
{
int n,e;
cout<<"拓扑排序测试,请输入顶点数和边数"<<endl;
cin>>n>>e;
DAG d[n];
InitGraph(n);
cout<<"请输入边的信息"<<endl;
for(int i=0;i<e;++i)
{
cin>>d[i].w1>>d[i].w2>>d[i].weight;
}
MakeGraph(d,e);
cout<<"拓扑排序结果"<<endl;
TopSort(n);
//system("pause");
return 0;
}