【数据结构】图----图的应用(拓扑排序)

一、基础概念

  1. 有向无环图 DAG :无回路的有向图,拓扑排序仅对 DAG 有效
  2. 拓扑排序 对 DAG 顶点排序,使得:任意有向边 <u , v> ,u 一定排在 v 前面
  3. 作用
  • 判断有向图是否有环
  • 任务调度、课程先后顺序、工程流程
  1. 特点
  • 拓扑序列不唯一
  • 有环图 → 不存在拓扑排序

二、算法核心思想(入度表法)

  1. 统计所有顶点入度
  2. 选取入度为 0 的顶点输出
  3. 删除该顶点所有出边(对应邻接点入度 -1)
  4. 重复 2~3,直到全部顶点输出 / 剩余顶点均有入度(有环)

三、完整代码(邻接表 + 拓扑排序 + 判环)

复制代码
#include <stdio.h>
#include <stdlib.h>
#define MAXN 105

// 边结点
typedef struct EdgeNode
{
    int adjvex;
    struct EdgeNode *next;
}EdgeNode;

// 顶点表
typedef struct Vex
{
    EdgeNode *first;
}Vex;

Vex G[MAXN];
int in[MAXN];   // 每个顶点入度
int n, m;       // n顶点 m边

// 拓扑排序
void TopSort()
{
    int stack[MAXN], top = 0;
    int cnt = 0;   // 统计输出顶点数

    // 1.所有入度为0的点入栈
    for(int i = 0; i < n; i++)
    {
        if(in[i] == 0)
            stack[top++] = i;
    }

    while(top != 0)
    {
        // 取出入度0的顶点
        int u = stack[--top];
        printf("%d ", u);
        cnt++;

        // 遍历u的所有出边
        EdgeNode *p = G[u].first;
        while(p != NULL)
        {
            int v = p->adjvex;
            in[v]--;    // 删除边<u,v>,v入度-1
            if(in[v] == 0)
                stack[top++] = v;
            p = p->next;
        }
    }

    // 判环
    if(cnt != n)
        printf("\n该有向图存在环,无合法拓扑序列\n");
    else
        printf("\n拓扑排序完成\n");
}

// 建图
void InitGraph()
{
    for(int i = 0; i < n; i++)
    {
        G[i].first = NULL;
        in[i] = 0;
    }
}

void AddEdge(int u, int v)
{
    EdgeNode *e = (EdgeNode*)malloc(sizeof(EdgeNode));
    e->adjvex = v;
    e->next = G[u].first;
    G[u].first = e;
    in[v]++;    // 终点入度+1
}

int main()
{
    scanf("%d%d", &n, &m);
    InitGraph();
    for(int i = 0; i < m; i++)
    {
        int u, v;
        scanf("%d%d", &u, &v);
        AddEdge(u, v);
    }
    TopSort();
    return 0;
}

四、关键总结

  1. 适用:有向无环图 DAG
  2. 核心操作:入度数组 + 删边减入度
  3. 判定有环:输出顶点个数 <n
  4. 时间复杂度:O(n+e)
  5. 序列不唯一:多个入度为 0 的点,选择顺序任意
相关推荐
ChillCoding几秒前
更新中:C++ STL库,查找排序(基础算法),数据结构,数学算法,竞赛相关基础
数据结构·c++·算法
智者知已应修善业6 分钟前
【51单片机使用IO组赋值方法实现无源蜂鸣器响时LED12亮不响时34亮】2024-3-7
c++·经验分享·笔记·算法·51单片机
珊瑚里的鱼16 分钟前
【动态规划】按摩师
算法·动态规划
Fms_Sa16 分钟前
贪心算法-背包问题
算法·贪心算法·c#
大雨淅淅22 分钟前
【机器人】ROS2 机械臂控制(MoveIt2)从入门到实战
人工智能·python·神经网络·学习·算法·机器学习·机器人
智者知已应修善业1 小时前
【51单片机0.1秒计时到21.0时点亮LED】2024-1-5
c++·经验分享·笔记·算法·51单片机
apcipot_rain1 小时前
计科八股20260606——二叉树、PCA、图深度学习、进程上下文、C语言预编译、文件读写、单精度浮点数
c语言·数据结构·算法·pca·图神经网络
scx_link1 小时前
逻辑回归的总结
算法·机器学习·逻辑回归
沐籽李1 小时前
Proteina-Complexa:NVIDIA 如何把蛋白 Binder 设计推进到全原子生成时代?
大数据·人工智能·算法·英伟达·蛋白质生成
落羽的落羽1 小时前
【项目】JsonRpc框架——开发实现2(业务层)
linux·数据结构·c++·人工智能·算法·json·动态规划