拓扑排序

定义

对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列。

  • 拓扑排序针对的是有向图
  • 不可以有环
  • 可以用一定的规则进行遍历整个图(遍历所有入度为0的点)

代码

拓扑排序的代码其实很简单。


    // 得到入度
    public int getIn(int n){
        int res=0;
        for(int i=0;i< graph.length;i++){
            if(graph[i][n]!=0){
                res+=1;
            }
        }
        return res;
    }
    public boolean isTopology(){
        Stack<Integer> stack = new Stack<>();
        // init
        for(int i=0;i< graph.length;i++){
            if(getIn(i)==0){ // 如果入度为0,我们加入栈
                stack.push(i);
            }
        }
        int visitedLen = 0;
        while (!stack.isEmpty()){
            int val = stack.pop();// 出栈
            System.out.println(names[val]);// 遍历的点
            for(int j=0;j< graph.length;j++){
                if(graph[val][j]!=0){
                    graph[val][j] = 0; //  将遍历的点的出度设为0;
                    if(getIn(j)==0){ //看他的出度是否有入度为0的点
                        stack.push(j);
                    }
                }
            }
            visitedLen++;
        }
        return visitedLen==graph.length;
}

后序

也可以用队列,拓扑排序的顺序是允许有一定的不同。

链表

class AoeNode{
    String name;
    ArcAoeNode firstArc;

    public AoeNode(String name) {
        this.name = name;
    }
}
class ArcAoeNode{
    int nextNode;
    int weight;
    ArcAoeNode nextArc;

    public ArcAoeNode(int nextNode, int weight) {
        this.nextNode = nextNode;
        this.weight = weight;
    }
}
public class CriticalPath {
    List<AoeNode> list;
    public CriticalPath(List<AoeNode> list) {
        this.list = list;
    }
    public int getin(int nodeIndex){
        int countIn=0;
        for(AoeNode aoe:list){
            ArcAoeNode arcAoeNode = aoe.firstArc;
            while (arcAoeNode!=null){
                if(arcAoeNode.nextNode == nodeIndex ){
                    countIn+=1;
                }
                arcAoeNode = arcAoeNode.nextArc;
            }
        }
        return countIn;
    }

    // topologic
    public boolean topologic(){

        Queue<Integer> queue = new LinkedList<>();
        int[] book = new int[list.size()];
        // init
        for(int i=0;i<list.size();i++){
            book[i] = getin(i);
            if(book[i]==0){
                queue.offer(i);
            }
        }
        int visitLen = 0;
        while (!queue.isEmpty()){
            int poll = queue.poll();
            System.out.println(list.get(poll).name+"---");
            ArcAoeNode arcAoeNode = list.get(poll).firstArc;
            while (arcAoeNode!=null){
                int node = arcAoeNode.nextNode;
                book[node]--;
                if(book[node]==0){
                    queue.offer(node);
                }
                arcAoeNode = arcAoeNode.nextArc;
            }
        }

        return visitLen==list.size();
    }


}
class testCriticalPath{
    public static void main(String[] args) {
        List<AoeNode> list = new ArrayList<>();
        // 加人点
        for(int i=0;i<10;i++){
            list.add(new AoeNode("V"+i));
        }
        // 加入边
        // v0
        AoeNode aoeNode = list.get(0);
        aoeNode.firstArc = new ArcAoeNode(1,3);
        aoeNode.firstArc.nextArc = new ArcAoeNode(2,4);
        // v1
        aoeNode = list.get(1);
        aoeNode.firstArc = new ArcAoeNode(3,5);
        aoeNode.firstArc.nextArc = new ArcAoeNode(4,6);
        // v2
        aoeNode = list.get(2);
        aoeNode.firstArc = new ArcAoeNode(3,8);
        aoeNode.firstArc.nextArc = new ArcAoeNode(5,7);
        // v3
        aoeNode = list.get(3);
        aoeNode.firstArc = new ArcAoeNode(4,3);
        // v4
        aoeNode = list.get(3);
        aoeNode.firstArc = new ArcAoeNode(6,9);
        aoeNode.firstArc.nextArc = new ArcAoeNode(7,4);
        // v5
        aoeNode = list.get(5);
        aoeNode.firstArc = new ArcAoeNode(7,6);
        // v6
        aoeNode = list.get(6);
        aoeNode.firstArc = new ArcAoeNode(9,2);
        // v7
        aoeNode = list.get(7);
        aoeNode.firstArc = new ArcAoeNode(8,5);
        // v8
        aoeNode = list.get(8);
        aoeNode.firstArc = new ArcAoeNode(9,3);
        // 图的完成
        CriticalPath criticalPath = new CriticalPath(list);
        System.out.println(criticalPath.topologic());

    }
}
posted @ 2022-01-10 16:01  度一川  阅读(82)  评论(0)    收藏  举报