javaee论坛

普通会员

225648

帖子

337

回复

351

积分

楼主
发表于 2017-09-04 08:20:56 | 查看: 331 | 回复: 2
拓扑排序(Topological Order)是指,将一个有向无环图(Directed Acyclic Graph简称DAG)进行排序进而得到一个有序的线性序列。

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

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

拓扑排序步骤

  1. 构造拓扑排序的结果队列T(topological);
  2. 计算所有顶点的入度;
  3. 如果存在入度为零且没有排序过的顶点,则
    3.1 将入度为0的顶点放入队列T,
    3.2 去掉以这些顶点为起点的边,
    3.3 标记这些顶点已经被排序过,
    3.4 返回步骤2,重新计算剩余定点入度
  4. 若果未排序的顶点入度都不为零,说明剩余的顶点组成了环,返回-1

Java实现

邻接矩阵图数据结构实现

承接前文的MatrixDG数据结构:

    //拓扑排序,如果无环,输出排序队列,返回1,若果有环,返回-1    public int topoSort(){        //设置是否访问过标记,初始化都是false        boolean[] visited=new boolean[size];        for(int i=0;i<size;i++){            visited[i]=false;        }        //拓扑排序结果存储队列        LinkedList<Integer> topo=new LinkedList<Integer>();        //调用拓扑排序算法        int result=topoSort(visited,topo);        //输出拓扑排序结果        if(result==1){            for(int i=0;i<topo.size();i++){                System.out.println(vertexs[topo.get(i)]+" ");            }        }        return result;    }    public int topoSort(boolean[] visited,LinkedList<Integer> topo){        //1,计算每个顶点的入度        int[] inDegree=new int[size];        for(int i=0;i<size;i++){            inDegree[i]=0;            for(int j=0;j<size;j++){                if(matrix[j][i]!=0&&visited[j]==false){                    inDegree[i]++;                }            }        }        //2,是否有环标记        boolean hasCircle=true;        for(int i=0;i<size;i++){            if(inDegree[i]==0&&visited[i]==false){//如果一个顶点入度为零且未被排序,则需要加入到队列中,且说明还没有发现环                hasCircle=false;                topo.add(i);//加入到队列中//                System.out.println(vertexs[i]);                visited[i]=true;//标记该顶点已被访问过            }                        }        if(hasCircle){//如果不存在还未被排序且入度为零的点,说明剩余的顶点构成了环,返回-1            System.out.println("Has Circle");            return -1;        }        //3,如果还可以继续进行排序,检验是否已全部排序过,通过已排序的顶点数量可以判断        if(size!=topo.size()){            return topoSort(visited,topo);        }else{            return 1; //如果都排序过了返回1        }    }

邻接表图数据结构实现

承接前文的ListDG数据结构:

    //拓扑排序,如果无环,输出排序队列,返回1,若果有环,返回-1    public int topoSort(){        //设置是否访问过标记,初始化都是false        boolean[] visited=new boolean[size];        for(int i=0;i<size;i++){            visited[i]=false;        }        //拓扑排序结果存储队列        LinkedList<Vertex> topo=new LinkedList<Vertex>();        //调用拓扑排序算法        int result=topoSort(visited,topo);        //输出拓扑排序结果        if(result==1){            for(int i=0;i<topo.size();i++){                System.out.println(topo.get(i).ch);            }        }        return result;    }    private int topoSort(boolean[] visited,LinkedList<Vertex> topo){        //1,计算每个顶点的入度        int[] inDegree=new int[size];        for(int i=0;i<size;i++){            Vertex node=vertexLists[i];            while(node!=null){                if(visited[i]==false){                    inDegree[getPosition(node.ch)]++;                }                node=node.next;            }            inDegree[i]--;//头节点不算所以减去1        }        //2,是否有环标记        boolean hasCircle=true;        for(int i=0;i<size;i++){            if(inDegree[i]==0&&visited[i]==false){//如果一个顶点入度为零且未被排序,则需要加入到队列中,且说明还没有发现环                hasCircle=false;                topo.add(vertexLists[i]);//加入到队列中//                System.out.println(vertexs[i]);                visited[i]=true;//标记该顶点已被访问过            }                        }        if(hasCircle){//如果不存在还未被排序且入度为零的点,说明剩余的顶点构成了环,返回-1            System.out.println("Has Circle");            return -1;        }        //3,如果还可以继续进行排序,检验是否已全部排序过,通过已排序的顶点数量可以判断        if(size!=topo.size()){            return topoSort(visited,topo);        }else{            return 1; //如果都排序过了返回1        }    }

普通会员

0

帖子

313

回复

324

积分
沙发
发表于 2022-04-29 11:32:09

围观

普通会员

0

帖子

299

回复

304

积分
板凳
发表于 2023-09-19 22:54:11

我最喜欢回复人少的贴子了,如果贴子沉了,我就会觉得是自己弄沉的,非常有成就感!如果贴子火了,那我有占了前排,这简直是稳赚不赔的生意嘛

您需要登录后才可以回帖 登录 | 立即注册

触屏版| 电脑版

技术支持 历史网 V2.0 © 2016-2017