拓扑排序c语言题目,数据结构--图(拓扑排序)

拓扑排序

应用对象:有向无环图(DAG)

AOV网:用一个有向图表示一个工程的各个子工程及其相互制约的关系,以顶点表示活动,弧表示活动之间的优先制约关系,称这种有向图为顶点表示活动的网,简称AOV网。

应用:拓扑排序

AOE网:用一个有向图表示一个工程的各个子工程及其相互制约的关系,以弧表示活动,以顶点表示活动开始或结束事件,称这种有向图为边表示活动的网,简称AOE网。

应用:关键路径

拓扑排序的定义:在AOV网没有回路的前提下,我们将全部活动排列成一个线性序列,使得若AOV网中有弧存在,则在这个序列中,i 一定排在 j 的前面,具有这种性质的线性序列称为拓扑有序序列,相应的拓扑有序排序算法称为拓扑排序。

拓扑排序流程

在有向网中选择一个没有前驱的顶点并将其依次添加到拓扑序列中。

从图中删除该顶点和所有以它为尾的弧。

重复上述两个步骤,直至将全部顶点添加进拓扑序列,或者图中不存在无前驱的顶点为止。

检测AOV网中是否存在环的方法

对有向图构造其顶点的拓扑有序序列,若网中所有顶点都在它的拓扑有序序列中,则该AOV网必定不存在环。

C语言应用举例

/**

* Note: The returned array must be malloced, assume caller calls free().

*/

int* findOrder(int numCourses, int** prerequisites, int prerequisitesSize, int* prerequisitesColSize, int* returnSize){

int* ret = (int*)malloc(sizeof(int)*numCourses);

//计算每门课的入度

int* inDegree = (int*)malloc(sizeof(int)*numCourses);

for(int i = 0; i < numCourses; i++){

inDegree[i] = 0;

}

for(int i = 0; i < prerequisitesSize; i++){

int a = prerequisites[i][0];

inDegree[a]++;

}

//拓扑排序

*returnSize = 0;

int* queue = (int*)malloc(sizeof(int)*numCourses+1);

int front = 0, rear = 0;

for(int i = 0; i < numCourses; i++){

if(inDegree[i] == 0){ //将入度为0的节点入队

queue[rear] = i;

rear = (rear+1)%(numCourses+1);

}

}

while(rear != front){

//出队

int cur = queue[front];

ret[*returnSize] = cur;

(*returnSize)++;

front = (front+1)%(numCourses+1);

//调整子节点的入度并将入度为0的节点入队

for(int i = 0; i < prerequisitesSize; i++){

int a = prerequisites[i][1], b = prerequisites[i][0];

if(a == cur){

inDegree[b]--;

if(inDegree[b] == 0){

queue[rear] = b;

rear = (rear+1)%(numCourses+1);

}

}

}

}

free(inDegree);

if(*returnSize != numCourses)*returnSize = 0;

return ret;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值