拓扑排序

       最近在学习一些图算法,看到了拓扑排序,这个算法上学期数据结构课上就学过,不过当时没有重视,早就忘光了,刚才好好看了一遍。拓扑排序是一个简单的算法,很容易理解,其思想是:找到图中入度为0的一个顶点并输出它,将以这个定点为起点的边全部删掉,然后再在剩余的点集中找到一个入度为0的点,重复这个过程,直至将全部点输出。

 

 

       拓扑排序算法的证明:在点集中找入度为0的点的实际意义是:找到不需要前提的工作,将这个工作做完后,以这个工作为前提的其他工作也就不需要这个工作做前提了,在图上的意义就是将以这个点为起点的边全部删除,重复这个过程直至输出全部的点。如果在中途找不到入度为0的点,那么也就代表当时剩的工作全部需要前提工作,也就是图中存在环,故此时不能进行拓扑排序。

拓扑排序实现如下:

 

 

#include<iostream> using namespace std; struct L { int v; L *next; }; class HEAD /*每个节点邻接表起点*/ { public: L *next; int id; /*表示该点的入度*/ HEAD(){ next=NULL; id=0; } }; HEAD head[1000]; void toposort(int n) /*拓扑排序*/ { int stack[1000],top=0,k=0,i,j; /*定义了一个辅助的栈,将当前入度为0的点全部入栈*/ for(i=1;i<=n;i++) if(!head[i].id) stack[top++]=i; while(top) /*如果当前栈不为空*/ { j=stack[--top]; /*在栈中取出一个点*/ cout<<j<<' '; k++; for(L *p=head[j].next;p!=NULL;p=p->next) /*删除所有以这个点为起点的边*/ { head[p->v].id--; if(!head[p->v].id) /*如果删除边后该边终点入度为0则将该点入栈*/ stack[top++]=p->v; } } if(k<n) /*如果输出的点小于n,则说明中途没有找到入度为0的点,也就不存在拓扑序列*/ cout<<"此图不存在拓扑序列!"<<endl; else cout<<endl; } int main() { int n,a,i; while(cout<<"输入顶点数/n"&&cin>>n&&n) { for(i=1;i<=n;i++) /*建立邻接表*/ while(cin>>a&&a) /*输入与i点邻接的点的坐标,以0结束*/ { L *p=new L; p->next=head[i].next; head[i].next=p; p->v=a; head[a].id++; } toposort(n); } return 0; }

 

 

 

你可能感兴趣的:(数据结构,工作,算法,Class)