zoukankan      html  css  js  c++  java
  • 十七、拓扑排序

    拓扑排序介绍

    拓扑排序(Topological Order)是指,将一个有向无环图(Directed Acyclic Graph简称DAG)进行排序进而得到一个有序的线性序列。

    这样说,可能理解起来比较抽象。下面通过简单的例子进行说明! 
    例如,一个项目包括A、B、C、D四个子部分来完成,并且A依赖于B和D,C依赖于D。现在要制定一个计划,写出A、B、C、D的执行顺序。这时,就可以利用到拓扑排序,它就是用来确定事物发生的顺序的。

    在拓扑排序中,如果存在一条从顶点A到顶点B的路径,那么在排序结果中B出现在A的后面。

    拓扑排序的算法图解

    以上图为例,来对拓扑排序进行演示。

    第1步:将B和C加入到排序结果中。 
        顶点B和顶点C都是没有依赖顶点,因此将C和C加入到结果集T中。假设ABCDEFG按顺序存储,因此先访问B,再访问C。访问B之后,去掉边<B,A>和<B,D>,并将A和D加入到队列Q中。同样的,去掉边<C,F>和<C,G>,并将F和G加入到Q中。 
        (01) 将B加入到排序结果中,然后去掉边<B,A>和<B,D>;此时,由于A和D没有依赖顶点,因此并将A和D加入到队列Q中。 
        (02) 将C加入到排序结果中,然后去掉边<C,F>和<C,G>;此时,由于F有依赖顶点D,G有依赖顶点A,因此不对F和G进行处理。 
    第2步:将A,D依次加入到排序结果中。 
        第1步访问之后,A,D都是没有依赖顶点的,根据存储顺序,先访问A,然后访问D。访问之后,删除顶点A和顶点D的出边。 
    第3步:将E,F,G依次加入到排序结果中。

    因此访问顺序是:B -> C -> A -> D -> E -> F -> G

    邻接矩阵:

    class Vertex
    {
    public char label; public Vertex(char lab)
    { label
    = lab; } } class DGraph
    {
    private final int MAX_VERTS = 20; private int nVerts; private Vertex vertexList[]; private int adjMat[][]; private char sortedArray[]; public DGraph()
    { vertexList
    = new Vertex[MAX_VERTS]; adjMat = new int[MAX_VERTS][MAX_VERTS]; nVerts = 0; for(int i=0;i<MAX_VERTS;i++) for(int j=0;j<MAX_VERTS;j++) adjMat[i][j] = 0; sortedArray = new char[MAX_VERTS]; } public void addVertex(char lab)
    { vertexList[nVerts
    ++] = new Vertex(lab); } public void addEdge(int start,int end)
    { adjMat[start][end]
    = 1; } public void displayVertex(int v)
    { System.out.println(vertexList[v].label); }
    public void topologicalSort()
    {
    int orig_nVerts = nVerts; while(nVerts>0)
    {
    int currentVertex = noSuccessors(); if(currentVertex == -1)
    { System.out.println(
    "Error:Graph has cycles"); return ; }
           //先找到拓扑排序的最后的节点 sortedArray[nVerts
    -1] = vertexList[currentVertex].label; deleteVertex(currentVertex); } System.out.print("Topologically sorted order:"); for(int j=0;j<orig_nVerts;j++) System.out.println(sortedArray[j]); System.out.println(); }
      //找到一个节点没有后继
    public int noSuccessors()
    {
    boolean isEdge; for(int row=0;row<nVerts;row++)
    { isEdge
    = false; for(int col=0;col<nVerts;col++)
    {
    if(adjMat[row][col]>0)
    { isEdge
    = true; break; } } if(!isEdge) return row; } return -1; } public void deleteVertex(int delVert)
    {
    if(delVert != nVerts-1)
    {
    for(int j=delVert;j<nVerts-1;j++) vertexList[j] = vertexList[j+1]; for(int row=delVert;row<nVerts-1;row++) moveRowUp(row,nVerts); for(int col=delVert;col<nVerts-1;col++) moveColLeft(col,nVerts-1); } nVerts--; } private void moveRowUp(int row,int length)
    {
    for(int col=0;col<length;col++) adjMat[row][col] = adjMat[row+1][col]; } private void moveColLeft(int col,int length)
    {
    for(int row=0;row<length;row++) adjMat[row][col] = adjMat[row][col+1]; } } public class MatrixDG_TOPO
    {
    public static void main(String[] args)
    { DGraph theGraph
    = new DGraph(); theGraph.addVertex('A'); // 0 theGraph.addVertex('B'); // 1 theGraph.addVertex('C'); // 2 theGraph.addVertex('D'); // 3 theGraph.addVertex('E'); // 4 theGraph.addVertex('F'); // 5 theGraph.addVertex('G'); // 6 theGraph.addVertex('H'); // 7 theGraph.addEdge(0, 3); // AD theGraph.addEdge(0, 4); // AE theGraph.addEdge(1, 4); // BE theGraph.addEdge(2, 5); // CF theGraph.addEdge(3, 6); // DG theGraph.addEdge(4, 6); // EG theGraph.addEdge(5, 7); // FH theGraph.addEdge(6, 7); // GH theGraph.topologicalSort(); // do the sort } }

    邻接链表:

    import java.util.ArrayList;
    class Vertex
    {
    public char label; public int index;//数组下标索引编号 public Edge firstEdge; public int inDegree;//入度 public Vertex(char lab){ index = 0; inDegree = 0; label = lab; firstEdge = null; } } class Edge
    {
    public int dest; public Edge nextEdge; public Edge(int dest)
    {
    this.dest= dest; nextEdge = null; } } class DGraph
    {
    private final int MAX_VERTS = 20; private int nVerts = 0; private Vertex[] vertexList; private ArrayList<Vertex> topoList; public DGraph()
    { vertexList
    = new Vertex[MAX_VERTS]; topoList = new ArrayList<Vertex>(); } public void addVertex(Vertex vertex)
    { vertex.index
    = nVerts; vertexList[nVerts++] = vertex; } public void addEdge(int start,int end)
    { vertexList[end].inDegree
    ++; Edge endEdge = new Edge(end); Edge currentEdge = vertexList[start].firstEdge; if(currentEdge==null)
    { vertexList[start].firstEdge
    = endEdge; }else
    { while(currentEdge.nextEdge!=null) currentEdge = currentEdge.nextEdge; currentEdge.nextEdge = endEdge; } } public void topologicalSort()
    {
    for(int i=0;i<nVerts;i++)
    { Vertex vertex
    = noPrevious(); if(vertex == null)
    { System.out.println(
    "Error:Graph has cycles"); return ; } topoList.add(vertex); deleteVertex(vertex); } } public Vertex noPrevious()
    {
    int i=0; for( ;i<nVerts;i++)
    {
    if(vertexList[i] != null && vertexList[i].inDegree==0) break; } if(i==nVerts) return null; else return vertexList[i]; } public void deleteVertex(Vertex vertex)
    { Edge currentEdge
    = vertex.firstEdge; if(currentEdge == null) return; while(currentEdge != null){ vertexList[currentEdge.dest].inDegree--; currentEdge = currentEdge.nextEdge; } /* //删除顶点数组中的一个顶点 for(int j=vertex.index;j<nVerts-1;j++){ vertexList[j] = vertexList[j+1]; vertexList[j].index = j; }*/ vertexList[vertex.index] = null; //nVerts--; } public void displayTopo()
    { System.out.println(
    "topologicalSort:"); for(int i=0;i<topoList.size();i++) System.out.print(topoList.get(i).label); System.out.println(""); } } public class ListDG_TOPO
    {
    public static void main(String[] args)
    { DGraph theGraph
    = new DGraph(); theGraph.addVertex(new Vertex('A'));// 0 theGraph.addVertex(new Vertex('B'));// 1 theGraph.addVertex(new Vertex('C'));// 2 theGraph.addVertex(new Vertex('D'));// 3 theGraph.addVertex(new Vertex('E'));// 4 theGraph.addVertex(new Vertex('F'));// 5 theGraph.addVertex(new Vertex('G'));// 6 theGraph.addVertex(new Vertex('H'));// 7 theGraph.addEdge(0, 3);// AD theGraph.addEdge(0, 4);// AE theGraph.addEdge(1, 4);// BE theGraph.addEdge(2, 5);// CF theGraph.addEdge(3, 6);// DG theGraph.addEdge(4, 6);// EG theGraph.addEdge(5, 7);// FH theGraph.addEdge(6, 7);// GH theGraph.addEdge(2, 1);// CB theGraph.addEdge(6, 5);// GF theGraph.topologicalSort(); theGraph.displayTopo(); } }
  • 相关阅读:
    吴裕雄--天生自然 JAVASCRIPT开发学习:函数定义
    吴裕雄--天生自然 JAVASCRIPT开发学习: JSON
    吴裕雄--天生自然 JAVASCRIPT开发学习: this 关键字
    吴裕雄--天生自然 JAVASCRIPT开发学习: 验证 API
    吴裕雄--天生自然 JAVASCRIPT开发学习: 表单验证
    吴裕雄--天生自然 JAVASCRIPT开发学习: 表单
    吴裕雄--天生自然 JAVASCRIPT开发学习: 变量提升
    吴裕雄--天生自然 JAVASCRIPT开发学习: 错误
    【codeforces 742A】Arpa’s hard exam and Mehrdad’s naive cheat
    【codeforces 742B】Arpa’s obvious problem and Mehrdad’s terrible solution
  • 原文地址:https://www.cnblogs.com/xxlong/p/5025619.html
Copyright © 2011-2022 走看看