拓扑排序:
若有 a->b, 则要求a一定要在b之前打印出来。
思路:
找到一个入度为0的节点,打印出来,把与之相邻的节点入度-1;
重复上面工作。
参考代码:
void Topsort(graph *g)
{
int *Indegree = new int[g->n];
int i;
/*统计入度*/
for(i=0;i<g->n;i++)
Indegree[i]=0;
for(i=0;i<g->n;i++)
{
struct edge *p=g->v[i].list;
while(p!=NULL)
{
Indegree[p->vertex]++;
p=p->next;
}
}
int *temp = new int[g->n]; //帮助判断每个节点是否已经打印出来
for(i=0;i<g->n;i++)
temp[i]=0;
int sum=0; //统计共打印了多少的数字
while(sum<g->n)
{
for(i=0;i<g->n;i++)
{
if(temp[i]==0 && Indegree[i]==0) //若没有打印出来且入度为0
{
temp[i]=1;
cout<<VName[i]<<" ";
sum++;
struct edge *p=g->v[i].list;
while(p!=NULL)
{
Indegree[p->vertex]--;
p=p->next;
}
}
}
}
}
此方法时间复杂度为O(V2)
可以进行优化:
建立一个队列,统计所有入度为0 的节点,添加到队列中。
从队列中弹出,打印它。再将与他有关的节点的入度-1.若发现入度变为0,则添加到队列中。
这样时间复杂度为O(V+E)
参考代码:
void quickTopsort(graph *g)
{
int *Indegree = new int[g->n];
int i;
/*统计入度*/
for(i=0;i<g->n;i++)
Indegree[i]=0;
for(i=0;i<g->n;i++)
{
struct edge *p=g->v[i].list;
while(p!=NULL)
{
Indegree[p->vertex]++;
p=p->next;
}
}
queue<int> v;
for(i=0; i<g->n;i++)
{
if(Indegree[i]==0)
v.push(i);
}
while(!v.empty())
{
int t=v.front();
v.pop();
cout<<VName[t]<<" ";
struct edge *p=g->v[t].list;
while(p!=NULL)
{
Indegree[p->vertex]--;
if(Indegree[p->vertex] ==0)
v.push(p->vertex);
p=p->next;
}
}
}