数据结构篇之topo排序
在离散数学角度看待Topo排序,即由集合U上的一个偏序(偏序指集合中仅有部分成员之间可比较)定义得到一个全序(全序指集合中全体成员之间均可比较)的操作就叫Topo排序。
Topo排序的基本思想是这样的:
在无环有向图中;
1. 找出入度为0的结点,记录在topo序列中,结点全部加入该序列后停止;
2. 删除该入度为0的结点以及以它为起始点的边,回到步骤1。
算法思想很容易理解,编程难度也不高。要进行topo排序操作,首先得先有个存储图的数据结构,由于在topo排序算法思想中提到删除结点时同时删除其邻接边,那么选择邻接表就再合适不过了,邻接表结构是点与邻边通过链表直接相连,访问邻边和邻接点很方便,删除邻边的操作只需要遍历该结点的邻接表并逐个删掉即可,选用邻接表作为存储结构也考虑到了在topo排序算法思想中暗藏的每次删除入度为0的结点及其邻边时,其邻接点的入度都会相应减1,那么邻接表结构也可方便我们对邻接点进行操作。
图的邻接表结构体如下:
const int MAXN = 20;
//邻接表结点结构体
typedef struct ArcNode{
int adjvex;//点的编号
struct ArcNode *nextarc;//邻边指针
}ArcNode;
//头结点结构体
typedef struct VNode{
char data[MAXN];//头结点数据信息
int indegree;//头结点的入度
ArcNode *firstarc;//头结点的第一条边(指针)
}VNode, AdjList[MAXN];
//图的邻接表结构体
typedef struct {
AdjList vertices;//头结点数组
int vexnum, arcnum;//结点个数,边个数
}ALGraph;
因为topo排序只能对无环有向图进行操作,但考虑到程序的健壮性,Topo排序程序应该面向所有有向图,包括无环和有环两种,当然,如果待排序的是有环有向图,那么该程序应该提供检测该图无法进行topo排序的功能,否则可以开始topo排序操作了。写一函数ALGraph_Create创建了一个有向图。