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

yizhihongxing

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日

相关文章

  • php实现快速排序的三种方法分享

    那么现在我将为您介绍“php实现快速排序的三种方法分享”的完整攻略。 什么是快速排序 快速排序(Quick Sort)通常被认为是对冒泡排序的一种改进。在冒泡排序中,需要进行多次的数据比较和交换操作,而快速排序与其不同之处在于它通过一个基准值将待排序的数组分成两个部分。在计算机领域,快速排序是一种常见的排序算法。 快速排序的常规实现思路 快速排序的常规实现思…

    算法与数据结构 2023年5月19日
    00
  • Golang实现四种负载均衡的算法(随机,轮询等)

    Golang实现四种负载均衡的算法(随机,轮询等) 负载均衡是指在分布式系统中,将工作负载分摊到多个计算资源来进行共同处理的技术。 Golang作为一种高性能、可靠性语言,天然适合做负载均衡,因此我们可以用Golang实现四种常用的负载均衡算法。 什么是负载均衡算法? 负载均衡算法是指在分发服务时,选择合适的服务器来处理请求的一种算法。负载均衡可分为静态负载…

    算法与数据结构 2023年5月19日
    00
  • 详解Bucket Sort桶排序算法及C++代码实现示例

    接下来我会详细讲解“详解Bucket Sort桶排序算法及C++代码实现示例”的完整攻略。 什么是桶排序算法? 目前,排序算法很多,常用的有冒泡排序、选择排序、插入排序、快速排序、归并排序等等算法。其中,桶排序(Bucket Sort)是比较特殊的一种排序方法。顾名思义,桶排序就是把数据分到不同的桶里,然后对每个桶里的数据进行排序。支持桶排序的数据类型必须是…

    算法与数据结构 2023年5月19日
    00
  • java垃圾收集器与内存分配策略详解

    Java垃圾收集器与内存分配策略详解 什么是垃圾收集器? Java垃圾收集器是Java虚拟机(JVM)提供的一种内存管理机制,它用于回收不再被程序引用的对象以节省内存空间。垃圾收集器通过对程序进行监控,可以自动发现未被引用的对象并将其回收。Java中的垃圾收集器大致可以分为如下四种: Serial Parallel Concurrent Mark Sweep…

    算法与数据结构 2023年5月19日
    00
  • C语言冒泡排序算法代码详解

    下面是“C语言冒泡排序算法代码详解”的完整攻略: 1. 冒泡排序算法原理 冒泡排序是一种基础的排序算法,其基本思想是将待排序的数组中的相邻元素两两比较,如果前面的元素大于后面的元素,则交换它们的位置,直到比较完所有元素。这样一轮比较交换之后,最大(或最小)的元素会被放到最后(或最前),然后再对剩下的元素重复以上步骤,直到所有元素都排好序为止。 2. 冒泡排序…

    算法与数据结构 2023年5月19日
    00
  • JS实现随机化快速排序的实例代码

    下面是JS实现随机化快速排序的完整攻略。 什么是随机化快速排序 随机化快速排序是一个常用的排序算法,它能够在 $O(n \log n)$ 的时间复杂度下对一个数组进行排序。该算法的实现非常高效,因为它使用了分治的思想,并且使用的是原地排序,即不需要额外的存储空间。随机化快速排序的核心是分区(partition)操作,该操作能够将一个数组分成两个部分,一部分是…

    算法与数据结构 2023年5月19日
    00
  • TypeScript调整数组元素顺序算法

    下面是详细的攻略: TypeScript调整数组元素顺序算法 在 TypeScript 中实现调整数组元素顺序的算法需要使用到以下两种方法: 方法一:splice() array.splice(startIndex, toRemove, …itemsToAdd) splice() 方法可以实现对数组中指定起始索引 startIndex 开始的若干元素的删…

    算法与数据结构 2023年5月19日
    00
  • c++冒泡排序详解

    c++冒泡排序详解 本文将对c++中的冒泡排序算法进行详解,并提供两个示例以方便读者理解。 冒泡排序的原理 冒泡排序算法通过不断比较相邻两个元素的大小,如果发现顺序不对就交换它们的位置,经过一次比较后就能确定一个元素的最终位置,再对剩余未排序的元素重复进行相同的操作,直到所有元素按照大小顺序排列完成。它的名字“冒泡”的意思即为像水泡一样,大的元素会一步一步向…

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