1. 拓扑排序
-
拓扑排序简介
假设在如下面的一张 有向图 中,顶点表示活动,弧表示活动之间的优先关系,这样的 有向图 顶点表示活动网,我们称之为 AOV 网。
上面 AOV 网的路径为:V1 -> V2 -> V3 -> V4 -> V5
或者 V1 -> V2 -> V3 -> V4 -> V5
设
G = (V,E)
是一个具有n个
顶点的 有向图,V 中的顶点V1、V2...Vn
,若满足从顶点Vi
到Vj
有一条路径,则在顶点序列Vi必须在Vj
之前,则我们称这样的顶点序列为 拓扑排序。所谓 拓扑排序,其实是对一个有向图构造拓扑序列的过程。
构造过程拓扑序列会产生两个结果:
1. 如果此网中的全部顶点被输出,说明是不存在环(回路)的AOV 网
2. 如果输出顶点小于总顶点数,说明是存在环(回路)的,不是AOV 网
-
拓扑排序实现
如上的一个AOV 网图,
那么AOV 网图怎么存储比较合适呢?我们可以设计一个 邻接表来存储,邻接表节点中增加一个变量,用来存储顶点的入度,邻接表节点结构如下:
顶点表结点
//顶点表结点
typedef struct VertexNode
{
//顶点入度
int in;
//顶点域,存储顶点信息
int data;
//边表头指针
EdgeNode *firstedge;
}VertexNode, AdjList[MAXVEX];
图结构:
//图结构
typedef struct
{
AdjList adjList;
//图中当前顶点数和边数
int numVertexes,numEdges;
}graphAdjList,*GraphAdjList;
思路分析:
1. 利用栈的特性,先将图网中所有入度为 0 的顶点下标入栈,
2. 循环遍历栈,直到栈为空
3. 栈顶元素出栈,并遍历与栈顶相连接的弧
3.1 获取与栈顶元素对应顶点连接的顶点
3.2 将与栈顶元素对应顶点连接的顶点入度减一
3.3 判断入度是否为 0 ,为 0 则入栈
先定义图、邻接矩阵和邻接表
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXEDGE 20
#define MAXVEX 14
#define INFINITYC 65535
/* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int Status;
// 邻接矩阵
typedef struct {
int vexs[MAXVEX];
int arc[MAXVEX][MAXVEX];
int numVertexes, numEdges;
}MGraph;
// 邻接表结构
// 边表节点
typedef struct EdgeNode{
int adjvex; // 邻接顶点域,存储顶点的下标
int weight; // 权值
struct EdgeNode *next; // 链域,存储下一个邻接点
}EdgeNode;
// 顶点表
typedef struct VertexNode{
int inCount; // 入度数
int data; // 顶点信息
EdgeNode *firstEdge; // 边表头指针
}VertexNode, AdjList[MAXVEX];
// 图结构
typedef struct {
AdjList adjList;
int numVertexes, numEdges;
}graphAdiList, *GraphAdjList;
由于一个一个的输入图的顶点和边,比较麻烦,我们定义一个函数,来