【数据结构与算法】拓扑排序

拓扑排序是一种有向图的排序。

结果是图中顶点的有序序列,这里假设是降序,那么序列中任意两个顶点vi>vj,如果在图中不存在从vj到vi的边,也就是排序的结果不与图中的顺序违背。

排序的思路就是BFS。

把整个图分为一层一层的结构,每一次输出一层,每一层层内的点的大小没有指定,所以可以按照任意顺序输出,但是层与层之间是有大小关系的,必须一致。

如果是找降序,那么这个思路转换为BFS就是,不断地寻找入度为0的点,放入一个队列Q,只要Q不为空,就拿出Q中的元素n,输出,然后删除n的临边,每删除一条就检测相邻的那个点是否也是入度为0,如果是,就加入到队列中,重复这个过程,直到队列为空。

如果Q为空了但是还没有遍历完所有的点,说明有环,不存在拓扑排序,否则存在。

如果想要升序排,那么上述过程就变为了不断寻找出度为0的点,思路不变。

下面是找降序的基于二维数组的代码:

public void topologySort(int[][] graph){
		int n = graph.length;
		List<Integer> r = new ArrayList<>();
		Queue<Integer> nodes = new LinkedList<>();
		//计算初始入度为0的点,存入nodes
		for(int i = 0; i < n; i++){
			boolean isAllZero = true;
			for(int j = 0; j < n; j++){
				if(graph[j][i] > 0){
					isAllZero = false;
					break;
				}
			}
			if(isAllZero)
				nodes.add(i);
		}
		while(!nodes.isEmpty()){
			int node = nodes.poll();
			r.add(node);
			for(int i = 0; i < n; i++){
				if(graph[node][i] > 0){
					graph[node][i] = 0;
					boolean isAllZero = true;
					for(int j = 0; j < n; j++){
						if(graph[j][i] > 0){
							isAllZero = false;
							break;
						}
					}
					if(isAllZero)
						nodes.add(i);
				}
			}
		}
		System.out.println(r);
	}

当然如果对空间复杂度没有特别的要求,这里不需要每一次用到度的时候都去计算一次。可以用一个map存放每一个顶点的度,这个map可以在第一次的for循环里面构建好。

然后在后面的for里,每当删除一条边时,相邻的顶点的map值减去一,在查看这个相邻点是否度为0时,只需要查看map即可,不需要再去遍历全部的节点来得到度了,由On变为了O1.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值