码迷,mamicode.com
首页 > 编程语言 > 详细

拓扑排序

时间:2015-07-20 23:33:30      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:算法

关于拓扑排序

  • 待排序的元素是什么? —— 有向图的结点

  • 按怎样的顺序? —— 如果存在边 v→w,则v要排在w的前面

算法

  • list ← []

  • 初始化队列,将入度为0的结点加入队列

    • 当队列非空:
      • v ← 出队
      • list.add(v)
      • w ← 遍历与v相邻的顶点
        • 将w的度数减1
        • 如果w的度数为0,则将w加入队列
  • 如果 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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!