拓扑结构排序

拓扑排序是一种对有向无环图(DAG)进行排序的算法。它将图中的节点按照依赖关系进行排序,使得所有的依赖关系都得到满足。

以下是拓扑排序的基本步骤:

  1. 创建一个队列(可以使用数组或队列数据结构),用于存储入度为 0 的节点。
  2. 初始化一个入度数组,用于记录每个节点的入度。
  3. 遍历图中的所有节点,统计每个节点的入度。入度表示有多少个节点指向该节点。
  4. 将入度为 0 的节点加入队列中。
  5. 循环执行以下步骤直到队列为空:
    • 从队列中取出一个节点,并将其加入排序结果中。
    • 遍历该节点的所有邻居节点,将其入度减 1。
    • 如果邻居节点的入度减为 0,则将其加入队列中。
  6. 如果排序结果中的节点数量等于图中的节点数量,则表示拓扑排序成功;否则,表示图中存在环,无法进行拓扑排序。

拓扑排序可以应用于诸如任务调度、编译顺序、依赖关系分析等场景。

注意:拓扑排序要求图是有向无环图(DAG),如果图中存在环,则无法进行拓扑排序。

下面是使用javascript,python和c++实现的方式:

function topologicalSort(numVertices, edges) {
  const graph = {}; // 邻接表
  const indegree = new Array(numVertices + 1).fill(0); // 入度数组

  // 初始化邻接表和入度数组
  for (let i = 1; i <= numVertices; i++) {
    graph[i] = [];
  }

  // 构建邻接表和入度数组
  for (const [u, v] of edges) {
    graph[u].push(v);
    indegree[v]++;
  }

  const result = [];
  const queue = [];

  // 将入度为 0 的节点加入队列
  for (let i = 1; i <= numVertices; i++) {
    if (indegree[i] === 0) {
      queue.push(i);
    }
  }

  // 拓扑排序
  while (queue.length > 0) {
    const node = queue.shift();
    result.push(node);

    // 更新邻居节点的入度
    for (const neighbor of graph[node]) {
      indegree[neighbor]--;

      // 若邻居节点入度为 0,则加入队列
      if (indegree[neighbor] === 0) {
        queue.push(neighbor);
      }
    }
  }

  return result;
}

示例用法:

const input = [
  [6, 8],
  [1, 2],
  [1, 3],
  [2, 4],
  [2, 5],
  [3, 4],
  [3, 6],
  [4, 6],
  [5, 6]
];

const numVertices = input[0][0];
const edges = input.slice(1).map(([u, v]) => [parseInt(u), parseInt(v)]);

const sorted = topologicalSort(numVertices, edges);
console.log(sorted); // 输出: [1, 2, 3, 5, 4, 6]

在这个例子中,输入包括点的个数和边的条数,以及每条边连接的两个点的信息。使用 topologicalSort 函数对输入进行拓扑排序,并将结果打印到控制台上。

请注意,上述实现假设输入的图是有向无环图(DAG),否则结果可能不正确。

from collections import defaultdict


def topologicalSort(numVertices, edges):
    graph = defaultdict(list)
    indegree = [0] * (numVertices + 1)

    # Build the graph and calculate the indegree of each vertex
    for u, v in edges:
        graph[u].append(v)
        indegree[v] += 1

    result = []
    queue = []

    # Enqueue vertices with indegree 0
    for i in range(1, numVertices + 1):
        if indegree[i] == 0:
            queue.append(i)

    # Perform topological sort
    while queue:
        node = queue.pop(0)
        result.append(node)

        # Update the indegree of neighboring vertices
        for neighbor in graph[node]:
            indegree[neighbor] -= 1

            # Enqueue vertices with indegree 0
            if indegree[neighbor] == 0:
                queue.append(neighbor)

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

vector<int> topologicalSort(int numVertices, vector<pair<int, int>>& edges) {
    vector<vector<int>> graph(numVertices + 1);
    vector<int> indegree(numVertices + 1, 0);

    // Build the graph and calculate the indegree of each vertex
    for (auto& edge : edges) {
        int u = edge.first;
        int v = edge.second;
        graph[u].push_back(v);
        indegree[v]++;
    }

    vector<int> result;
    queue<int> q;

    // Enqueue vertices with indegree 0
    for (int i = 1; i <= numVertices; i++) {
        if (indegree[i] == 0) {
            q.push(i);
        }
    }

    // Perform topological sort
    while (!q.empty()) {
        int node = q.front();
        q.pop();
        result.push_back(node);

        // Update the indegree of neighboring vertices
        for (int neighbor : graph[node]) {
            indegree[neighbor]--;

            // Enqueue vertices with indegree 0
            if (indegree[neighbor] == 0) {
                q.push(neighbor);
            }
        }
    }

    return result;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值