有向图的拓扑排序

拓扑排序的算法实现
描述:
首先找到入度为0的顶点,然后再将它的直接后继的所有顶点的入度数减1,然后输出该点,再找入度为0,如此循环,一直到找不到入度为0 的点。如果整个图的所有顶点都找到了,那么G中就没有有向环,而且输出的序列就是一个拓扑有序的序列。
但是由于可能存在同时两个点的入度都为0,所以拓扑序列不唯一。

#include <iostream>
#include <cstdio>
using namespace std;
struct Edge{
    int dest;//表示目标顶点
    int value;//边的权值
    Edge * link;//链表下一元素
};
void TopologicalSort(int n,Edge* edge[n]){
    int degree[n];//计算入度数,然后加到degree数组中
    memset(degree, 0, n*sizeof(int));
    Edge *l;
    for(int i=0;i<n;i++){
        l=edge[i];
        while(l){
            degree[l->dest]++;
            l=l->link;
        }
    }
    //top表示入度为0 的顶点的栈的栈顶
    int top=-1;
    for(int i=0;i<n;i++){
        if(degree[i]==0){
            degree[i]=top;
            top=i;
        }
    }
    for(int i=0;i<n;i++){
        if(top==-1){
        //表示没有入度为0的顶点
            cout<<"存在有向环"<<endl;
            return;
        }
        else{
            int j=top;
            top=degree[top];
            cout<<j<<endl;
            l=edge[j];
            while(l){
                if(--degree[l->dest]==0){
                    //新的入度为0的点
                    degree[l->dest]=top;
                    top = l->dest;
                }
                //下一个后继点
                l=l->link;
            }
        }
    }
}
int main(){
    int n;//顶点个数
    cin>>n;
    Edge* edge[n];
    int u,v;
    Edge *l;
    //初始化邻接表
    for(int i=0;i<n;i++){
        edge[i]=NULL;
    }
    while(cin>>u>>v){
        l=new Edge;
        l->dest=v;
        l->link=edge[u];
        edge[u]=l;
    }
    TopologicalSort(n, edge);
    return 0;
}
### 有向图拓扑排序算法及其实现 #### 拓扑排序的概念 拓扑排序是对有向无环(DAG,Directed Acyclic Graph)的种线性化操作。它的目标是将中的所有顶按某种顺序排列,使得如果存在条从顶 \( u \) 到顶 \( v \) 的边,则在排序结果中 \( u \) 出现在 \( v \) 前面[^1]。 #### 算法原理 拓扑排序的核心思想在于利用深优先搜索(DFS)或者计数的方法来逐步移除中的节并构建排序序列。以下是两种常见的实现方式: 1. **基于 DFS 的方法** - 对于每个未访问过的节执行深优先遍历。 - 在回溯过程中记录下当前节,并将其加到最终的结果列表头部。 - 如果在整个过程中发现了个已经存在于栈中的节,则说明中有环,无法完成拓扑排序[^4]。 2. **基于 Kahn 算法表法)** - 初始化个队列,将所有为零的节其中。 - 取出队首的个节,将其添加至结果集,并删除该节及其对应的所有出边。 - 更新受影响节值;若有新的为零的节,则继续加队列。 - 若最后仍有剩余节未能处理,则表明原含有环结构[^3]。 #### Python 实现示例 下面提供了种基于 Kahn 算法的 Python 版本实现: ```python from collections import deque, defaultdict def topological_sort(graph): # 计算每个节 indegree = {node: 0 for node in graph} for nodes in graph.values(): for node in nodes: indegree[node] += 1 # 将所有0的节队列 queue = deque([node for node in indegree if indegree[node] == 0]) result = [] while queue: current_node = queue.popleft() result.append(current_node) # 遍历相邻节并减少它们的 for neighbor in graph.get(current_node, []): indegree[neighbor] -= 1 if indegree[neighbor] == 0: queue.append(neighbor) # 如果结果长小于总节数量,表示存在环 if len(result) != len(indegree): raise ValueError("Graph contains a cycle and cannot be sorted.") return result # 测试用例 if __name__ == "__main__": adj_list = { 'A': ['B', 'C'], 'B': ['D'], 'C': ['D'], 'D': [], 'E': ['F'], 'F': [] } try: print(topological_sort(adj_list)) # 输出可能为['A', 'E', 'C', 'B', 'F', 'D'] except ValueError as e: print(e) ``` 此代码片段展示了如何通过维护字典和辅助队列来进行有效的拓扑排序计算过程[^2]。 --- #### Java 实现示例 这里还给出了份基于深优先搜索策略下的 Java 实现版本: ```java import java.util.*; public class TopoLogicalSort { private Map<Integer, List<Integer>> adjacencyList; private Set<Integer> visited; private Deque<Integer> stack; public TopoLogicalSort(Map<Integer, List<Integer>> adjacencyList){ this.adjacencyList = adjacencyList; this.visited = new HashSet<>(); this.stack = new ArrayDeque<>(); } public void sort(){ for(Integer vertex : adjacencyList.keySet()){ if(!visited.contains(vertex)){ dfs(vertex); } } } private void dfs(int vertex){ visited.add(vertex); if(adjacencyList.containsKey(vertex)){ for(int adjacentVertex : adjacencyList.get(vertex)){ if(!visited.contains(adjacentVertex)){ dfs(adjacentVertex); } } } stack.push(vertex); // Post-order processing step. } public List<Integer> getSortedOrder(){ return new ArrayList<>(stack); } public static void main(String[] args){ Map<Integer, List<Integer>> graph = new HashMap<>(); graph.put(5, Arrays.asList(2, 0)); graph.put(4, Collections.singletonList(0)); graph.put(2, Collections.singletonList(3)); graph.put(3, Collections.singletonList(1)); graph.put(1, null); graph.put(0, null); TopoLogicalSort sorter = new TopoLogicalSort(graph); sorter.sort(); System.out.println(sorter.getSortedOrder()); } } ``` 上述程序定义了个 `TopoLogicalSort` 类用来封装整个逻辑流程,并采用递归形式完成了对各顶的探索工作[^4]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值