数据结构-----图
图分为有向图和无向图。
图的存储:邻接矩阵,邻接表,链式前向星。
图的拓扑排序的前提:有向、无环
那么拓扑排序还可以判断一个有向图有没有环
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* findOrder(int numCourses, int** prerequisites, int prerequisitesSize, int* prerequisitesColSize, int* returnSize) {
int* ans = (int*)malloc(sizeof(int) * 2001);//存放答案的数组
int head[2000] = {0};//存放每个节点指向的边
int to[4000] = {0};//存放每条边指向的节点
int next[4000] = {0};//存放每条边指向的下一条边
int d[2000] = {0};//入度数组
int cnt = 1;//边的编号从1开始
int len = 0;//答案数组的长度
int q[4000];//队列
int l = 0;//队列头
int r = 0;//队列尾
for (int i = 0; i < prerequisitesSize; i++) {//遍历边数组
int from = prerequisites[i][1];//注意是先修了b才能修a,所以是b指向a
int tp = prerequisites[i][0];//那么被指向的就是a
d[tp]++;//被指向,那么它对应的度就加一
next[cnt] = head[from];//新的边先指向老的边
to[cnt] = tp;//新的边指向的节点赋值
head[from] = cnt++;//新的边成为对应节点的头边
}
for (int i = 0; i < numCourses; i++) {//遍历度数组,找到度为0的点
if (d[i] == 0) {//如果点为0
q[r++] = i;//把点放入队列
}
}
while(l != r) {//队列不为空
ans[len++] = q[l];//弹出队列头作为答案
for (int j = head[q[l]]; j; j = next[j]) {//取出节点在链式前向星的头边,然后让它的邻居的入度都减一
if (--d[to[j]] == 0) {//减一之后是0
q[r++] = to[j];//把对应的节点放入队列
}
}
l++;//队列头之前没有加一
}
if (len != numCourses) {//如果结果长度和正确的排序长度不相等,代表图有环不能拓扑排序
*returnSize = 0;//返回空数组
return NULL;
}
*returnSize = len;//返回的长度赋值
return ans;//返回结果数组
}

浙公网安备 33010602011771号