Loading

拓扑排序

基本概念

拓扑序:如果图中从V到W有一条有向路径,则V一定排在W之前。满足此条件的顶点序列称为一个拓扑序,那么拓扑排序就是获得一个拓扑序的过程。另外,如果有合理的拓扑序,则必定是有向无环图。

拓扑排序算法

下面介绍一个比较好的拓扑排序算法

伪代码如下:

void TopSort(){
	for(图中每个顶点V)
		if(Indegree[V]==0)
			Enqueue(Q,V);
	while(!IsEmpty(Q)){
		V=Dequeue(Q);
		输出V,或者记录V的输出序号;
		cnt++;
		for(V的每个邻接点W)
			if(--Indegree[W]==0)
				Enqueue(Q,W);
	}
	if(cnt!=|V|)
		ERROR("图中有回路");
}

C语言实现如下:

bool TopSort(LGraph Graph, Vertex TopOrder[]){		//对Graph进行拓扑排序,TopOrder[]顺序存储排序后的顶点下标
	int Indegree[MaxVertexNum],cnt;
	Vertex V;
	PtrToAdjVNode W;
	Queue Q=CreateQueue(Graph->Nv);

	for(V=0;V<Graph->Nv;V++)		//初始化Indegree[]
		Indegree[V]=0;

	for(V=0;V<Graph->Nv;V++)		//遍历图,得到Indegree[]
		for(W=Graph->G[V].FirstEdge;W;W=W->Next)
			Indegree[W->AdjV]++;		//对有向边<V,W->AdjV>累计终点的入度

	for(V=0;V<Graph->Nv;V++)
		if(Indegree[V]==0)		//将所有入度为0的顶点入队
			AddQ(Q,V);

	cnt=0;
	while(!IsEmpty(Q)){
		V=DeleteQ(Q);		//弹出一个入度为0的顶点
		TopOrder[cnt++]=V;		//将V存为结果序列的下一个元素
		for(W=Graph->G[V].FirstEdge;W;W=W->Next)		//对于V的每一个邻接点W->AdjV
			if(--Indegree[W->AdjV]==0)		//若删除V使得W->AdjV的入度为0
				AddQ(Q,W->AdjV);		//则将W->AdjV入队
	}

	if(cnt!=Graph->Nv)		//图中有回路
		return fasle;
	else
	 	return true;
}

时间复杂度T=O(|V|+|E|),此算法也可以用来检测有向图是否是无环图。

posted @ 2020-07-05 18:54  Kinopio  阅读(296)  评论(0编辑  收藏  举报