拓扑排序DFS+BFS

问题描述:如下图所示,在有向图中,如何将所有节点排序,使得节点满足其在下一个节点之前,可能存在多种解,只需要返回一个即可。

 DFS: 遍历节点过程中,将节点化为三种状态:在搜索中,未搜索,已搜索。每次取未搜索过的节点,依次沿着其下一个节点,深度优先搜索,直到没有下一个节点。之后将已搜索过的节点添加到栈中。

tip: 当有向图存在环时,下一个节点状态为在搜索中,此时停止遍历。

import java.util.ArrayList;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;

public class TopologySort {
    static List<List<Integer>> nextNode;
    static int[] visit;
    static boolean valid; // 判断是否有环
    static Deque<Integer> res;
    public static void main(String[] args) {
        int[][] preNode = new int[][]{{1,2},{1,4},{4,5},{5,6},{2,3},{3,6}};
        int numNode = 6+1;
        boolean isValid = topologySort(numNode, preNode);
        System.out.println(isValid);
        while(!res.isEmpty()) {
            System.out.print(res.poll() + " ");
        }
    }
    public static boolean topologySort(int numNode, int[][] preNode) {
        nextNode = new ArrayList<List<Integer>>();
        visit = new int[numNode];
        for (int i = 0; i < numNode; i++) {
            nextNode.add(new ArrayList<>());
        }
        for (int i = 0; i < preNode.length; i++) {
            nextNode.get(preNode[i][0]).add(preNode[i][1]);
        }
        valid = true;
        res = new LinkedList<>();
        for (int i = 1; i < numNode && valid; i++) {
            if(visit[i] == 0)
               dfs(i);
        }
        return valid;
    }
    public static void dfs(int u) {
        visit[u] = 1;

        for (int v: nextNode.get(u)) {
            if(visit[v] == 0){
                dfs(v);
                if(!valid) {
                    return;
                }
            } else if(visit[v] == 1) {
                valid = false;
                return;
            }
        }

        visit[u] = 2;
        res.push(u);

    }
}

 BFS: 使用队列来处理遍历,每次取入度为0的节点,如上图所示节点0开始,并将其所有的下一个节点的入度减一,后依次取入度为0的节点,直到没有入度为0的节点。

tip: 当有向图中存在环时,最后剩下的节点入度不为0;

import java.util.ArrayList;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;

public class TopologySort {
    static List<List<Integer>> nextNode;
    static int[] inNodes;
    static Deque<Integer> queue;
    static Deque<Integer> ans;
    public static void main(String[] args) {
        int[][] preNode = new int[][]{{1,2},{1,4},{4,5},{5,6},{2,3},{3,6}};
        int numNode = 6+1;
        boolean isValid = topologySort(numNode, preNode);
        System.out.println(isValid);
        while(!ans.isEmpty()) {
            System.out.print(ans.poll() + " ");
        }
    }
    public static boolean topologySort(int numNode, int[][] preNode) {
        nextNode = new ArrayList<List<Integer>>();
        inNodes = new int[numNode];
        for (int i = 0; i < numNode; i++) {
            nextNode.add(new ArrayList<>());
        }
        for (int i = 0; i < preNode.length; i++) {
            nextNode.get(preNode[i][0]).add(preNode[i][1]);
            inNodes[preNode[i][1]]++;
        }

        queue = new LinkedList<>();
        for (int i = 1; i < numNode; i++) {
            if(inNodes[i] == 0) {
                queue.offer(i);
            }
        }
        ans = new LinkedList<>();
        while(!queue.isEmpty()) {
            int u = queue.poll();
            ans.offer(u);
            for(int v: nextNode.get(u)) {
                inNodes[v]--;
                if(inNodes[v] == 0) {
                    queue.offer(v);
                }
            }
        }
        return ans.size() == numNode-1;
    }

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值