算法-拓扑排序-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. 课程表||

相关推荐
dongf20192 分钟前
R 语言 逻辑斯蒂回归
开发语言·数据分析·回归·r语言
fie88894 分钟前
基于有限体积法(FVM)的MATLAB流体力学求解程序
算法·matlab
Irissgwe4 分钟前
C++ STL unordered系列关联式容器详解
开发语言·c++·stl·关联式容器
m0_547486666 分钟前
华南农业大学《C语言程序设计》期末试卷及答案2018-2025年PDF
c语言·开发语言·pdf·c语言程序设计
fqbqrr8 小时前
2606C++,C++构的多态
开发语言·c++
biter down9 小时前
从 0 到 1 搭建 Python 接口自动化测试框架(博客系统实战)
开发语言·python
小欣加油9 小时前
leetcode56 合并区间
c++·算法·leetcode·职场和发展
lqqjuly9 小时前
前沿算法深度解析(二)
人工智能·算法·机器学习
徐小夕10 小时前
万字长文!千万级文档 RAG 知识库系统落地实践
前端·算法·github