[数据结构]拓扑排序

拓扑排序

AOV网络 用有向图的顶点表示活动,顶点之间的有向边表示活动间的先后关系,这种有向图称为顶点表示活动网络,简称AOV网络。

当限制各个活动只能串行进行时,可以将AOV网络中所有顶点排列成一个线性序列,且vi必须在vj之前,我们就称这个线性序列为拓扑序列,把对AOV网构造拓扑序列的操作称为拓扑排序

拓扑排序算法:
1、在网中选择一个入度为0的顶点并输出
2、删除该顶点和所有由它发出的边
3、重复操作,直到没有入度为0的顶点

许多情况下入度为0的顶点不止一个,这样就可以给出多种拓扑排序,且每种都可以保证先后顺序。

邻接矩阵

邻接矩阵中,入度由这个顶点对应列上1的个数决定,所以算法框架为:
1、取1作为第一个新序号
2、找一个没有得到新序号的全0矩阵,若没有则停止寻找,如果所有列都得到了新序号,拓扑排序完成,否则说明有向图中有环存在,无法形成拓扑排序。
3、把新序号赋给找到的列,并将该列对应的顶点输出
4、将找到的列所对应的行置全0
5、新序号+1,重复执行2~5

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

typedef char vertexType;
typedef int edgeType;
typedef struct{
	vertexType vexs[100];
	edgeType arc[100][100];
	int vexnumber,edgenumber;
}MGraph;

void createMGraph(MGraph *G){
	int i,j,k,w;
	printf("请输入顶点数和边数\n");
	scanf("%d,%d",&G->vexnumber,&G->edgenumber);  //读取顶点数和边数 
	for(i=0;i<G->vexnumber;i++){
		scanf(&G->vexs[i]);
	}
	for(i=0;i<G->vexnumber;i++){
		for(j=0;j<G->vexnumber;j++){
			G->arc[i][j]=-1;
		}
	}
	for(k=0;k<G->vexnumber;k++){
		printf("请输入边(vi,vj)的上下标i,j和权值w\n");
		scanf("%d,%d,%d",&i,&j,&w);
		G->arc[i][j]=w;
		G->arc[j][i]=w;  //设置对称矩阵 
		}
}


void topoSortA(MGraph *g,int n){    //用邻接矩阵求拓扑排序
	int i,j,k,t,v,D[n];
	for(i=0;i<n;i++){
		D[i]=0;
	}
	v=1;              //新序号变量置1
	for(k=0;k<n;k++){
		for(j=0;j<n;j++){       //寻找全0列
			if(D[j]==0){
				t=1;
				for(i=0;i<n;i++){
					if(g->arc[i][j]==1){
						t=0;
						break;          //第j列上有1  跳出循环
					}
					if(t==1){
						m=j;
						break;
					}                      //找到第j列为全0列
				}
		}
				if(j!=n){
					D[m]=v;             //将新序号赋给找到的列
					printf("%d\t",g->vexs[m]);         //输出排序结果
					for(i=0;i<n;i++){
						g->arc[m][i]=0;         //找到的列相应行置全0
						v++;                   //新序号+1
					}
				}
				else break;
			}
		}
		if(v<n) printf("\n The network has a cycle\n");
	}

邻接表

typedef char vertexType;
typedef int edgeType;
typedef struct edgenode{     //邻接链表结点 
	int adjvex;
	edgeType weight;
	struct edgenode *next;          //链域 
}edgenode;

typedef struct{
	vertexType vertex;      //顶点域 
	egdenode *link;         //指针 
	int id;
}vexnode;

vexnode ga[n];          //顶点表 

void topoSortB(vexnode ga[]){
	edgenode p;
	int i,j,k,m=0,top=-1;      //top为栈指针 
	for(i=0;i<n;i++){                 //初始化,建立入度为0的顶点链栈 
		if(ga[i].id==0){
			ga[i].id=top;
			top=i;
		}
	}
	while(top!=-1){    //栈非空执行排序 
		j=top;
		top=ga[top].id;       //第j+1个顶点退栈 
		printf("%d\t",ga[j].vertex);      //输出退栈顶点 
		m++;      //输出顶点计数 
		p=ga[j].link;
		while(p){            //删去所有以vj+1为起点的边 
			k=p->adjvex;
			ga[k].id--;
			if(ga[k].id==0){
				ga[k].id=top;
				top=k;
			}
			p=p->next;       //找下一条边 
		}
	}
	if(m<n) printf("\n The network has a cycle\n");
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值