C/C++浅析邻接表拓扑排序算法的实现

C/C++浅析邻接表拓扑排序算法的实现

什么是拓扑排序

在图论中,若存在一种拓扑序列,使得对于任意的有向边(u,v),u在序列中都在v的前面,则称该图为拓扑排序,该序列称为拓扑序列。拓扑排序是一个有向无环图(DAG, Directed Acyclic Graph)的一种线性序列。

拓扑排序算法的实现

拓扑排序算法的实现一般基于邻接表,其核心思路为:先将所有入度为0的点入队,扫描队列中的点,把该点所指向的点的入度减1,若减为0,则将该点入队。最后,若可入队的点数小于图中点数,则该图不存在拓扑序列。

关键代码实现

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

const int MAXN = 10005;

struct Edge {
    int to, next;
} edges[MAXN];
int head[MAXN], degree[MAXN];
int cnt;

void addEdge(int u, int v) {
    edges[cnt].to = v;
    edges[cnt].next = head[u];
    head[u] = cnt++;
    degree[v]++;
}

bool topsort(int n) {
    queue<int> q;
    for (int i = 1; i <= n; i++) {
        if (!degree[i]) q.push(i);
    }

    int cnt = 0;
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        cnt++;
        for (int i = head[u]; ~i; i = edges[i].next) {
            int v = edges[i].to;
            degree[v]--;
            if (!degree[v]) {
                q.push(v);
            }
        }
    }

    return cnt == n;
}

int main()
{
    int n, m;
    cin >> n >> m;
    memset(head, -1, sizeof(head));
    for (int i = 0; i < m; i++) {
        int u, v;
        cin >> u >> v;
        addEdge(u, v);
    }

    if (!topsort(n)) {
        cout << "No topsort!" << endl;
        return 0;
    }
    for (int i = 1; i <= n; i++) {
        cout << i << " ";
    }
    cout << endl;

    return 0;
}

示例说明

示例1

输入:

7 9
7 6
7 5
6 4
6 3
5 4
5 2
4 1
3 1
2 1

输出:

7 6 5 4 3 2 1 

示例2

输入:

6 6
1 2
1 3
2 4
2 5
3 6
4 6

输出:

No topsort!

性能分析

时间复杂度:O(V+E)。其中,V为图中点数,E为图中边数。因为算法需要遍历每一个点和边。

空间复杂度:O(V+E)。其中,V为点数,E为边数。因为需要存储每个点的边列表以及每个点的入度。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C/C++浅析邻接表拓扑排序算法的实现 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • C语言实现冒泡排序算法的示例详解

    C语言实现冒泡排序算法的示例详解 冒泡排序是一种简单但效率较低的排序算法。它重复遍历要排序的数列,每次比较相邻两个元素,如果顺序不对就交换两元素顺序。该算法的时间复杂度为 O(n^2)。 以下是C语言实现冒泡排序的示例代码: #include <stdio.h> int main() { int arr[] = {5, 3, 8, 6, 4}; …

    算法与数据结构 2023年5月19日
    00
  • 利用JavaScript实现的10种排序算法总结

    作为“利用JavaScript实现的10种排序算法总结”的作者,首先需要明确以下内容: 熟悉10种排序算法的原理与流程 理解JavaScript作为一门编程语言的特点和应用场景 知道如何将算法的流程用JavaScript代码实现 针对以上内容,可以采取以下步骤: 梳理10种排序算法的流程和实现方式,用markdown文本形式编写对应的标题和文本,例如: 插入…

    算法与数据结构 2023年5月19日
    00
  • C语言 奇偶排序算法详解及实例代码

    C语言奇偶排序算法详解及实例代码 本篇文章将详细讲解C语言中奇偶排序算法的原理、实现方法及具体的实例代码,并通过两个示例说明其使用方法。 原理介绍 奇偶排序算法又叫交替排序算法,是一种简单但较慢的排序算法,通常用于小型数据集中的排序。该算法通过使用两个线程分别对奇数位置和偶数位置的元素进行比较和交换来实现排序。 该算法的原理如下: 从头到尾扫描一遍待排序数组…

    算法与数据结构 2023年5月19日
    00
  • JS折半插入排序算法实例

    下面是介绍JS折半插入排序算法的完整攻略。 什么是折半插入排序算法? 折半插入排序是插入排序的一种改进算法,它的基本思路是利用二分查找找到某个待排元素在已排序序列中插入位置。 折半插入排序算法的时间复杂度为 O(nlogn),比普通插入排序 O(n^2)快。 折半插入排序算法实现步骤 折半插入排序算法的实现步骤如下: 从第二个元素开始,将整个序列分为已排序区…

    算法与数据结构 2023年5月19日
    00
  • JS前端面试必备——基本排序算法原理与实现方法详解【插入/选择/归并/冒泡/快速排序】

    JS前端面试必备——基本排序算法原理与实现方法详解 在前端面试中,算法是一个必考的考点,掌握一些基本的排序算法对于一个前端工程师来说是非常重要的。 排序算法的分类 排序算法可以按照许多不同的标准进行分类: 平均时间复杂度 空间复杂度 稳定性 内部排序和外部排序 在这篇文章中,我们将按照时间复杂度从小到大的顺序介绍以下五个基本的排序算法:插入排序、选择排序、归…

    算法与数据结构 2023年5月19日
    00
  • JS实现的全排列组合算法示例

    下面针对 “JS实现的全排列组合算法示例” 给出完整攻略。 什么是全排列组合算法? 全排列组合是指将一个集合中的元素排成一列,可以有不同的排列方式,这些不同的排列方式就称为全排列。当从这个集合中取出一部分排成一列时,称为排列,而取出一部分组合称为组合。 JS实现全排列组合算法的步骤 具体实现全排列组合算法的步骤如下: 定义需要排列和组合的数组或字符串; 定义…

    算法与数据结构 2023年5月19日
    00
  • PHP冒泡排序算法代码详细解读

    PHP冒泡排序算法代码详细解读 什么是冒泡排序? 冒泡排序是一种简单的排序算法,通过交换相邻元素比较和交换的方式进行排序。该算法会重复遍历待排序的数列,每次比较相邻的两个元素,如果顺序错误就交换位置。重复执行这个过程,直到整个数列有序。 算法实现过程 以下是基于PHP语言实现的冒泡排序代码,对应的注释为算法的实现过程说明。 function bubbleSo…

    算法与数据结构 2023年5月19日
    00
  • python快速排序代码实例

    Python 快速排序 (Quick Sort) 是一种排序算法,它利用分治思想来快速排序一个数组或序列。该算法的时间复杂度为 O(nlogn)。 要理解快速排序算法,我们需要掌握以下概念: 基准值 (pivot):排序过程中用于比较的值。在每一轮的排序过程中,基准值会将数组或序列分成两部分。 子数组 (subarray):对于一个数组或序列,它的一部分就是…

    算法与数据结构 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部