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

相关推荐
码码哈哈0.07 分钟前
LangChain 快速入门(从0到可用)
开发语言·python·langchain
_小草鱼_14 分钟前
【搜索与图论】DFS算法(深度优先搜索)
算法·深度优先·图论·回溯·递归
熊文豪21 分钟前
Java 入门指南
开发语言·python
I_LPL42 分钟前
hot100 栈专题
算法·
小菜鸡桃蛋狗43 分钟前
C++——类和对象(上)
开发语言·c++
伯恩bourne1 小时前
Google Guava:Java 核心工具库的卓越之选
java·开发语言·guava
2401_879503411 小时前
C++中的观察者模式变体
开发语言·c++·算法
lsx2024061 小时前
Rust 迭代器
开发语言
阿贵---1 小时前
C++中的备忘录模式
开发语言·c++·算法
房开民1 小时前
paddle 文本检测识别模型转为onnx
开发语言·r语言·paddle