算法-拓扑排序-C

记录算法使用场景和代码实现

算法简介

拓扑排序算法是将有向图看成一条序列。

使用场景

我所知的两种场景如下:

  • 拓扑排序判环
  • 打印一种拓扑排序序列

代码实现

拓扑排序判环

步骤:

  1. 建图:每个节点记录入度属性
  2. 找到入度为0的所有结点,入栈
  3. 出栈结点,删除该结点------该结点指向的结点入度减一,如果入度为0,入栈
  4. 如果所有结点都删掉,没有环,否则有环
c 复制代码
typedef struct Graph {
    int **graph;
    int *in;
    int *graphColSize;
} Graph;

Graph CreateGraph(int n, int **prerequisites, int prerequisitesSize) {
    Graph G;
    int **graph = (int **)malloc(sizeof(int *)*(n));
    int *graphColSize = (int *)malloc(sizeof(int)*(n));
    int *in = (int *)malloc(sizeof(int)*(n));
    memset(graph, 0, sizeof(int *)*(n));
    memset(graphColSize, 0, sizeof(int)*(n));
    memset(in, 0, sizeof(int)*(n));
    for(int i=0; i<prerequisitesSize; i++) {
        int a = prerequisites[i][0];
        int b = prerequisites[i][1];
        // printf("%d %d\n", a, b);
        if(graph[b] == NULL) {
            graph[b] = (int *)malloc(sizeof(int)*n);
        }
        graph[b][graphColSize[b]++] = a;
        in[a]++;
    }
    G.graph = graph;
    G.graphColSize = graphColSize;
    G.in = in;
    return G;
}

bool IsHasCircle(Graph *graph, int graphSize) {
    int stack[2000];
    int topPos = 0;
    int zeroInNodeNum = graphSize;
    for(int i=0; i<graphSize; i++) {
        if(graph->in[i] == 0) {
            stack[topPos++] = i;
        }
    }
    if(topPos == 0) return false;
    while (topPos > 0) {
        int top = stack[--topPos];
        zeroInNodeNum--;
        for(int i=0; i<graph->graphColSize[top]; i++) {
            int neighborId = graph->graph[top][i];
            (graph->in[neighborId])--;
            if(graph->in[neighborId] == 0) {
                stack[topPos++] = neighborId; 
                
            }
        }
    }
    return zeroInNodeNum == 0;
}

leetcode-207. 课程表

打印一种拓扑排序序列

算法过程不多作介绍,只是在删除结点时,记录结果。

c 复制代码
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* findOrder(int numCourses, int** prerequisites, int prerequisitesSize, int* prerequisitesColSize, int* returnSize) {
    Graph graph = CreateGraph(numCourses, prerequisites, prerequisitesSize);
    int *res = (int *)malloc(sizeof(int)*numCourses);
    int cnt = 0;
    int stack[2000];
    int topPos = 0;
    int zeroInNodeNum = numCourses;
    for(int i=0; i<numCourses; i++) {
        if(graph.in[i] == 0) {
            stack[topPos++] = i;
        }
    }
    while (topPos > 0) {
        int top = stack[--topPos];
        res[cnt++] = top;
        zeroInNodeNum--;
        for(int i=0; i<graph.graphColSize[top]; i++) {
            int neighborId = graph.graph[top][i];
            (graph.in[neighborId])--;
            if(graph.in[neighborId] == 0) {
                stack[topPos++] = neighborId; 
            }
        }
    }
    if(zeroInNodeNum != 0) *returnSize = 0;
    else *returnSize = cnt;
    return res;
}

leetcode-210. 课程表||

相关推荐
Yfhonier2 分钟前
岛屿数量(DFS)
算法·深度优先
橘子汽水1683 分钟前
Leetcode15:三数之和
java·数据结构·算法
黄金龙PLUS6 分钟前
ASCON置换算法的优缺点
算法·网络安全·密码学·哈希算法·同态加密
catchadmin9 分钟前
免费可商用 PHP 管理后台 CatchAdmin V5.4.0 发布,新增短信服务能力
开发语言·php
邪修king11 分钟前
Re:Linux 系统篇(十六):进程篇(五):O (1) 调度算法深度解析 —— 优先级数组、位图优化与活跃 / 过期双队列
linux·运维·算法
小白学大数据19 分钟前
API 调用错误处理实战:分层定位、有纪律地重试与可观测性设计
开发语言·网络·人工智能
Yfhonier28 分钟前
6440. 极大连通图个数(DFS)
数据结构·算法·深度优先
玖玥拾39 分钟前
LeetCode 1 两数之和
算法·leetcode·职场和发展
Cccp.12340 分钟前
【leetcode】(一)认识复杂度和简单排序算法
算法·排序算法