标签:算法
待排序的元素是什么? —— 有向图的结点
按怎样的顺序? —— 如果存在边 v→w,则v要排在w的前面
list ← []
初始化队列,将入度为0的结点加入队列
如果 list.size() < 顶点总数,则抛出有环异常
package com.gmail.dailyefforts.ds.graph;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Scanner;
public class TopoSort {
    public static List<Integer> topoSort(DirectedGraph g) {
        List<Integer> list = new ArrayList<>();
        Queue<Vertex> q = new LinkedList<>();
        for (Vertex v : g.vertices()) {
            if (v.inDegree == 0) {
                q.add(v);
            }
        }
        while (!q.isEmpty()) {
            Vertex v = q.poll();
            list.add(v.id);
            for (Vertex w : v.adj()) {
                if (--w.inDegree == 0) {
                    q.add(w);
                }
            }
        }
        if (list.size() < g.V()) {
            throw new RuntimeException("There is cycle.");
        }
        return list;
    }
    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(new FileInputStream("./input.txt"));
        final int V = sc.nextInt();
        final int E = sc.nextInt();
        DirectedGraph g = new DirectedGraph(V);
        for (int e = 0; e < E; e++) {
            int v = sc.nextInt();
            int w = sc.nextInt();
            g.addEdge(v, w);
        }
        System.out.println(TopoSort.topoSort(g));
        sc.close();
    }
}
相关有向图的实现:
package com.gmail.dailyefforts.ds.graph;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class DirectedGraph {
    private final int V;
    private int E;
    private List<Vertex> vertices;
    public DirectedGraph(int V) {
        this.V = V;
        vertices = new ArrayList<>();
        for (int v = 0; v < V; v++) {
            vertices.add(new Vertex(v));
        }
    }
    public int V() {
        return V;
    }
    public int E() {
        return E;
    }
    public void addEdge(int from, int to) {
        Vertex v = vertices.get(from);
        Vertex w = vertices.get(to);
        v.addAdj(w);
        v.outDegree++;
        w.inDegree++;
        E++;
    }
    public int inDegree(int v) {
        Vertex vertex = vertices.get(v);
        return vertex.inDegree;
    }
    public int outDegree(int v) {
        Vertex vertex = vertices.get(v);
        return vertex.outDegree;
    }
    public Iterable<Vertex> vertices() {
        return vertices;
    }
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append(String.format("%d vertices, %d edges\n", V, E));
        for (int v = 0; v < V; v++) {
            builder.append(v + ": " + vertices.get(v).adj);
            builder.append(‘\n‘);
        }
        return builder.toString();
    }
    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(new FileInputStream("./input.txt"));
        final int V = sc.nextInt();
        final int E = sc.nextInt();
        DirectedGraph g = new DirectedGraph(V);
        for (int e = 0; e < E; e++) {
            int v = sc.nextInt();
            int w = sc.nextInt();
            g.addEdge(v, w);
        }
        System.out.println(g);
        sc.close();
    }
}
拓扑排序:0, 1, 2, 4, 3
拓扑排序可用于任务调度,例如,C语言是算法的先修课程,算法是操作系统的先修课程。我们就应该在时序上做如此安排:C语言 → 算法 → 操作系统
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:算法
原文地址:http://blog.csdn.net/programs/article/details/46975281