图的拓扑排序(java版本)

  • 抽象出一种图的结构,经典的图结构

一种通用的图的定义

Node

public class Node {
    int out;
    int in;
    int value;
    ArrayList<Node>  nexts;
    ArrayList<Edge> edges;
    public Node(int value){
        this.out = 0;
        this.in = 0;
        this.value = value;
        this.nexts = new ArrayList<>();
        this.edges = new ArrayList<>();
    }

}

Graph

public class Graph {
    Map<Integer, Node> nodes;
    Set<Edge> edges;
    public Graph(){
        nodes = new HashMap<>();
        edges = new HashSet<>();
    }
}

Edge

public class Edge {
    public int weight;
    public Node from;
    public Node to;

    public Edge(int weight, Node from, Node to) {
        this.weight = weight;
        this.from = from;
        this.to = to;
    }
}

图的宽度优先遍历

GraphBFS

public class GraphBFS {
    public void graphBFS(Node start) {
        if (start == null) {
            return;
        }
        Queue<Node> queue = new LinkedList<>();
        HashSet<Node> set = new HashSet<>();
        queue.add(start);
        set.add(start);
        while (!queue.isEmpty()) {
            Node cur = queue.poll();
            System.out.println(cur.value);
            for (Node next : cur.nexts) {
                if (!set.contains(next)) {
                    set.add(next);
                    queue.add(next);
                }
            }
        }
    }
}

图的深度优先遍历

一条路没走完就走到死,走到了就往上

GraphDFS

public class GraphDFS {
    public void graphDFS(Node start){
        if(start == null){
            return;
        }
        Stack<Node> stack = new Stack<>();
        HashSet<Node> set = new HashSet<>();
        stack.add(start);
        set.add(start);
        while(!stack.isEmpty()){
            Node cur = stack.pop();
            for(Node next:cur.nexts){
                if(!set.contains(next)){
                    stack.push(cur);
                    stack.push(next);
                    set.add(next);
                    System.out.println(next.value);
                    break;
                }
            }
        }
    }
}

1.迭代自己压栈,2.栈里面放着是整条路径,3.加入就打印(处理数据)

图的拓扑排序算法

  • 通用拓扑排序,一般是根据入度来计算

TopologySort

public class TopologySort {
    // directed graph and no loop
    public static List<Node> sortedTopology(Graph graph) {
        HashMap<Node, Integer> imMap = new HashMap<>();
        //入度为零的队列, 优先处理
        Queue<Node> zeroInQueue = new LinkedList<>();
        for(Node node : graph.nodes.values()){
            imMap.put(node, node.in);
            if(node.in == 0){
                zeroInQueue.add(node);
            }
        }
        ArrayList<Node> result = new ArrayList<>();
        while(!zeroInQueue.isEmpty()){
            Node cur = zeroInQueue.poll();
            result.add(cur);
            for(Node next:cur.nexts){
                imMap.put(next, imMap.get(next) - 1);
                if(imMap.get(next) == 0){
                    zeroInQueue.add(next);
                }
            }
        }
        return result;
    }
}
  • BFS拓扑排序

TopologicalOrderBFS

public class TopologicalOrderBFS {
    public static class DirectedGraphNode{
        public int label;
        public ArrayList<DirectedGraphNode> neighbors;
        public DirectedGraphNode(int x){
            this.label = x;
            neighbors = new ArrayList<DirectedGraphNode>();
        }
    }
    public static ArrayList<DirectedGraphNode> topSort(ArrayList<DirectedGraphNode> graph){
        HashMap<DirectedGraphNode, Integer> indegreeMap = new HashMap<>();
        for(DirectedGraphNode cur : graph){
            indegreeMap.put(cur, 0);
        }
        for(DirectedGraphNode cur : graph){
            for(DirectedGraphNode next: cur.neighbors){
                indegreeMap.put(next, indegreeMap.get(next) + 1);
            }
        }
        Queue<DirectedGraphNode> queue = new LinkedList<>();
        //入度为0加如队列
        for(DirectedGraphNode cur : indegreeMap.keySet()){
            if(indegreeMap.get(cur) == 0){
                queue.add(cur);
            }
        }
        ArrayList<DirectedGraphNode> res = new ArrayList<>();
        while(!queue.isEmpty()){
            DirectedGraphNode cur = queue.poll();
            res.add(cur);
            for(DirectedGraphNode next : cur.neighbors){
                indegreeMap.put(next, indegreeMap.get(next) - 1);
                //入度为0 加入队列
                if(indegreeMap.get(next) == 0){
                    queue.offer(next);
                }
            }
        }
        return res;
    }
}
  • DFS 拓扑排序

TopologicalOrderDFS

public class TopologicalOrderDFS {
    public static class DirectedGraphNode {
        public int label;
        public ArrayList<DirectedGraphNode> neighbors;

        public DirectedGraphNode(int x) {
            this.label = x;
        }
    }

    public static class Record {
        public DirectedGraphNode node;
        public int deep;

        public Record(DirectedGraphNode node, int deep) {
            this.node = node;
            this.deep = deep;
        }
    }

    public static class MyComparator implements Comparator<Record> {
        @Override
        public int compare(Record o1, Record o2) {
            return o2.deep - o1.deep;
        }
    }


    public static ArrayList<DirectedGraphNode> topSort(ArrayList<DirectedGraphNode> graph) {
        HashMap<DirectedGraphNode, Record> order = new HashMap<>();
        for (DirectedGraphNode cur : graph) {
            f(cur, order);
        }
        //存储所有的node节点
        ArrayList<Record> records = new ArrayList<>();
        for (Record r : order.values()) {
            records.add(r);
        }
//        排序?
        records.sort(new MyComparator());
        records.sort(new MyComparator());
        ArrayList<DirectedGraphNode> directedGraphNodes = new ArrayList<>();
        for (Record r : records) {
            directedGraphNodes.add(r.node);
        }
        return directedGraphNodes;
    }

    //计算每个node的深度
    public static Record f(DirectedGraphNode cur, HashMap<DirectedGraphNode, Record> order) {
        if (order.containsKey(cur)) {
            return order.get(cur);
        }
        int follow = 0;
        for (DirectedGraphNode next : cur.neighbors) {
            follow = Math.max(follow, f(next, order).deep);
        }
        Record ans = new Record(cur, follow + 1);
        order.put(cur, ans);
        return ans;
    }
}
posted @   行舟QAQ  阅读(180)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示