拓扑排序:
若有 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;
}
}
}
本文详细介绍了拓扑排序算法的基本思想及其两种实现方式。一种是通过遍历节点并递减相邻节点的入度来实现,时间复杂度为O(V^2)。另一种是通过队列优化,将入度为0的节点加入队列并依次处理,时间复杂度降低为O(V+E)。
333

被折叠的 条评论
为什么被折叠?



