拓扑排序及逆拓扑排序

拓扑排序其实就是对有向无环图的顶点的一种排序,每个顶点出现且只出现一次。

对一个AOV网进行拓扑排序的方法:

1、从AOV网中选择一个入度为0的顶点并输出;

2、从网中删除该顶点和所有以它为起点的有向边;

3、重复1和2直到当前的AOV网为空或当前网中不存在入度为0的顶点为止;

1、拓扑排序算法 

该算法中假设使用邻接表作为存储结构:

//拓扑排序
#define Maxsize 100
int indegree[Maxsize];         //存储当前顶点的入度
int print[Maxsize];           //记录拓扑序列
Stack S;                //存储入度为0的顶点

bool TopologicalSort(Graph G)
{
	InitStack(S);           //初始化栈
	for(int i=0;inextarc)//将所有i指向的顶点的入度减1,并且将入度减为0的顶点压入栈中 
		{
			v=p->adjvex;
			if(!(--indegree[v]))
			{
				push(S,v)
			}
		}
		if(count

时间复杂度为:O(|V|+|E|);若采用邻接矩阵存储时,其时间复杂度为O(|V|^2);

2、使用DFS进行拓扑排序 

祖先结点的DFS函数结束时间大于子孙结点的DFS函数结束时间,利用DFS求出各顶点结束时间,对于拓扑排序,就是将结束时间从大到小排序。

 //深度优先遍历实现的拓扑排序
 bool visit[Maxnum];      //标记数组,防止顶点被多次访问 
 void DFSTraverse(Graph G)
 {
 	for(int i=0;i=0;w=NextNeighbor(G,V,W))  //从顶点v出发,深度优先遍历G
	{
	 	if(!visit[w]);
	 	DFS(G,w);
	} 
	time+=1;
	finishTime[v]=time; 
  } 

3、逆拓扑排序 

逆拓扑排序的步骤:

1、从AOV网中选择一个出度为0的顶点并输出;

2、从网中删除该顶点和所有以它为终点的有向边;

3、重复1和2,直到当前的AOV网为空;

#define Maxsize 100
//拓扑排序
int Dedegree[Maxsize];         //存储当前顶点的出度
int print[Maxsize];           //记录拓扑序列
Stack S;                //存储出度为0的顶点

bool TopologicalSort(Graph G)
{
	InitStack(S);           //初始化栈
	for(int i=0;inextarc)//将指向i的顶点的出度减1,并且将出度减为0的顶点压入栈中 
		{
			v=p->adjvex;
			if(!(--Dedegree[v]))
			{
				push(S,v)
			}
		}
		if(count

4、DFS遍历实现逆拓扑排序 

 //DFS实现的逆拓扑排序
 bool visit[Maxnum];      //标记数组,防止顶点被多次访问 
 void DFSTraverse(Graph G)
 {
 	for(int i=0;i=0;w=NextNeighbor(G,V,W))  //从顶点v出发,深度优先遍历G
	{
	 	if(!visit[w]);
	 	DFS(G,w);
	} 
	cout<

总结:

1、拓扑排序和逆拓扑排序序列都可能不唯一;

2、若图中有环,则不存在拓扑排序序列或者逆拓扑排序序列; 

你可能感兴趣的:(算法,数据结构,图论)