图-拓扑排序

认识:

        一个较大的工程往往被划分成许多子工程,我们把这些子工程称作活动(activity)。在整个工程中,有些子工程(活动)必须在其它有关子工程完成之后才能开始,也就是说,一个子工程的开始是以它的所有前序子工程的结束为先决条件的,但有些子工程没有先决条件,可以安排在任何时间开始。通常,我们把这种顶点表示活动、边表示活动间先后关系的有向图称做顶点活动网(Activity On Vertex network),简称AOV网。

AOV网的特点:无向无环图,因为如果有环就会有循环依赖,不符合项目特征。

        那工程的执行顺序是什么呢,拓扑排序就是工程的执行顺序。

        拓扑排序常用来确定一个依赖关系集中,事物发生的顺序。例如,在日常工作中,可能会将项目拆分成A、B、C、D四个子部分来完成,但A依赖于B和D,C依赖于D。为了计算这个项目进行的顺序,可对这个关系集进行拓扑排序,得出一个线性的序列,则排在前面的任务就是需要先完成的任务。

代码实现

package 算法.图.拓扑排序;

import 算法.图.其他结构转换.CreateGraph01;
import 算法.图.其他结构转换.CreateGraphInterface;
import 算法.图.其他结构转换.IntArr;
import 算法.图.基础节点.Graph;
import 算法.图.基础节点.Node;

import java.util.*;

/**
 * 拓扑排序
 *
 */
public class TopologySort {
    public static void main(String[] args) {
        //构建图
        IntArr matrix = new IntArr();
        int[][] arr = {
                {1,1,2},
                {1,2,3},
                {2,1,4},
                {3,2,4},
                {4,1,5}
        };
        matrix.setArr(arr);
        CreateGraphInterface createGraph = new CreateGraph01();
        Graph graph = createGraph.createGraph(matrix);
        //输出拓扑排序
        List<Node> nodes = sortedTopology(graph);
        System.out.println(nodes.toString());
    }

    /**
     * 输出拓扑排序顺序
     * @param graph
     * @return
     */
    public static List<Node> sortedTopology(Graph graph){
        //存储节点入度
        HashMap<Node,Integer> hashMap = new HashMap<>();
        //队列,用于存放入度为0的节点
        Queue<Node> queue = new LinkedList<>();
        List<Node> list = new ArrayList<>();
        //第一次循环 将节点放入map里面,如果有入度为0的放到队列里
        for(Node node:graph.nodes.values()){
            hashMap.put(node,node.in);
            if (node.in == 0) {
                queue.add(node);
            }
        }
        //循环队列里的节点直到为空,并且减少map中后续节点的入度,当入度为0的时候 放入队列
        while (!queue.isEmpty()){
            Node n1 = queue.poll();
            for (Node next:n1.nexts) {
                Integer in = hashMap.get(next);
                in--;
                //当后面的节点入度为0的时候 加入到队列
                if (in.equals(0)) {
                    queue.add(next);
                }
                hashMap.put(next,in);
            }
            list.add(n1);
        }

        return list;
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值