昨天开始学的拓补排序,自己总结了一下拓补排序算法的思路。
1.首先构造一个能够存储图的数据类型,能把边之间的关系存起来。
2.找到这些边的初始入度为0的顶点,将这些顶点存到一个数组当中,我看的这个书当中把这些点存入一个像栈一样的数组,初始化完成之后用这个数组中的顶点和跟他相关联的顶点的入度减去1.
3接下来就是拓补排序非常重要的一步,用这些初始入度为0的顶点找到与之相关联的顶点,把这些顶点的入度减去1之后,如果他们的入度为0,就把他们放入那个类似于栈的数组(其实这是个for循环查找与当前入度为0的顶点关联的顶点减去1后入度是否为0),当与一个顶点相关联的顶点全部找到之后,他们的入度如果为0就已经放在了类似于栈的数组当中,下次循环开始的时候当然是先用他们(栈的特点)。
4.到最后,如果整个图的顶点没有回路,那么这个栈最后就会是空的,如果不是空,就说明有回路。
//用临接表的形式进行图的构建
struct node
{
int nodevalue;
node * next;
};
struct graph
{
int value;
node * head;
};
graph date[550];
int x[550];//用来存储拓补排序的最终结果
//用来找到每个顶点的入度,indegree指针指向一个存储顶点的数组
void findnum(graph * it,int * indegree)
{
for (int i=1;i<=n;++i)
{
indegree[i]=0;
}
for (int i=1;i<=n;++i)
{
node * p=it[i].head;
while(p)
{
++indegree[p->nodevalue];
p=p->next;
}
}
}
//拓补排序
int tuobu(graph * it)
{
int top=-1;
int all=0;
int indegree[550];
findnum(it,indegree);
for (int i=n;i>=1;--i)
{
if (indegree[i]==0)
{
indegree[i]=top;
top=i;
}
}//这个for循环当中的数组就是类似用栈,用它来实现栈的作用,刚看的时候感觉好神奇。。。。
all=toplist(it,indegree,top);//最关键的函数,用来把每个入度为0的顶点存入到x数组当中
if (all<n)
{
return 0;
}
return 1;
}
//
int toplist(graph * it,int * indegree,int top)
{
int nd=0;
while(top!=-1)
{
int p=top;
top=indegree[top];
x[nd++]=p;
for (node * i=it[p].head;i!=nullptr;i=i->next)//for循环找到每个入度为0的顶点相关联的顶点,把他们的入度减1,如果减1后是0,就放入类似于栈的数组indegree中,再下次使用
{
int k=i->nodevalue;
if (--indegree[k]==0)
{
indegree[k]=top;
top=k;
}
}
}
return nd;
}
第一次写这么长得博文,,写出来的目的就是希望自己以后忘了再看看记起来,,也算是一种总结,可能还有很多不足的地方,希望看到的人多多包涵,多给出意见