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

相关推荐
小陈工1 小时前
Python Web开发入门(十七):Vue.js与Python后端集成——让前后端真正“握手言和“
开发语言·前端·javascript·数据库·vue.js·人工智能·python
海清河晏1111 小时前
数据结构 | 单循环链表
数据结构·算法·链表
H Journey1 小时前
C++之 CMake、CMakeLists.txt、Makefile
开发语言·c++·makefile·cmake
wuweijianlove5 小时前
算法性能的渐近与非渐近行为对比的技术4
算法
_dindong5 小时前
cf1091div2 C.Grid Covering(数论)
c++·算法
AI成长日志5 小时前
【Agentic RL】1.1 什么是Agentic RL:从传统RL到智能体学习
人工智能·学习·算法
lly2024066 小时前
C 标准库 - `<stdio.h>`
开发语言
沫璃染墨6 小时前
C++ string 从入门到精通:构造、迭代器、容量接口全解析
c语言·开发语言·c++
jwn9996 小时前
Laravel6.x核心特性全解析
开发语言·php·laravel
迷藏4946 小时前
**发散创新:基于Rust实现的开源合规权限管理框架设计与实践**在现代软件架构中,**权限控制(RBAC)** 已成为保障
java·开发语言·python·rust·开源