美文网首页
图的结构 BFS DFS

图的结构 BFS DFS

作者: shoulda | 来源:发表于2018-07-17 11:09 被阅读0次
 //下面是图的结构
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;
    }

}


//下面是边的结构
public class Node {
    public int value;
    public int in;
    public int out;
    public ArrayList<Node> nexts;
    public ArrayList<Edge> edges;

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

//下面是图的结构
public class Graph {
    public HashMap<Integer,Node> nodes;
    public HashSet<Edge> edges;

    public Graph() {
        nodes = new HashMap<>();
        edges = new HashSet<>();
    }
}

//生成图
public class GraphGenerator {

    public static Graph createGraph(Integer[][] matrix) {
        Graph graph = new Graph();
        for (int i = 0; i < matrix.length; i++) {
            Integer from = matrix[i][0];
            Integer to = matrix[i][1];
            Integer weight = matrix[i][2];
            if (!graph.nodes.containsKey(from)) {
                graph.nodes.put(from, new Node(from));
            }
            if (!graph.nodes.containsKey(to)) {
                graph.nodes.put(to, new Node(to));
            }
            Node fromNode = graph.nodes.get(from);
            Node toNode = graph.nodes.get(to);
            Edge newEdge = new Edge(weight, fromNode, toNode);
            fromNode.nexts.add(toNode);
            fromNode.out++;
            toNode.in++;
            fromNode.edges.add(newEdge);
            graph.edges.add(newEdge);
        }
        return graph;
    }

}

题目:BFS

一个队列,一个set集合

public static void bfs(Node node) {
        if (node == null) {
            return;
        }
        Queue<Node> queue = new LinkedList<>();
        HashSet<Node> map = new HashSet<>();
        queue.add(node);
        map.add(node);
        while (!queue.isEmpty()) {
            Node cur = queue.poll();
            System.out.println(cur.value);
            for (Node next : cur.nexts) {
                if (!map.contains(next)) {
                    map.add(next);
                    queue.add(next);
                }
            }
        }
    }

题目:DFS

public static void dfs(Node node) {
        if (node == null) {
            return;
        }
        Stack<Node> stack = new Stack<>();
        HashSet<Node> set = new HashSet<>();
        stack.add(node);
        set.add(node);
        System.out.println(node.value);
        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;
                }
            }
        }
    }

题目:Kruskal算法

package basic_class_05;

import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.PriorityQueue;
import java.util.Set;

//undirected graph only
public class Code_05_Kruskal {

    // Union-Find Set
    public static class UnionFind {
        private HashMap<Node, Node> fatherMap;
        private HashMap<Node, Integer> rankMap;

        public UnionFind() {
            fatherMap = new HashMap<Node, Node>();
            rankMap = new HashMap<Node, Integer>();
        }

        private Node findFather(Node n) {
            Node father = fatherMap.get(n);
            if (father != n) {
                father = findFather(father);
            }
            fatherMap.put(n, father);
            return father;
        }

        public void makeSets(Collection<Node> nodes) {
            fatherMap.clear();
            rankMap.clear();
            for (Node node : nodes) {
                fatherMap.put(node, node);
                rankMap.put(node, 1);
            }
        }

        public boolean isSameSet(Node a, Node b) {
            return findFather(a) == findFather(b);
        }

        public void union(Node a, Node b) {
            if (a == null || b == null) {
                return;
            }
            Node aFather = findFather(a);
            Node bFather = findFather(b);
            if (aFather != bFather) {
                int aFrank = rankMap.get(aFather);
                int bFrank = rankMap.get(bFather);
                if (aFrank <= bFrank) {
                    fatherMap.put(aFather, bFather);
                    rankMap.put(bFather, aFrank + bFrank);
                } else {
                    fatherMap.put(bFather, aFather);
                    rankMap.put(aFather, aFrank + bFrank);
                }
            }
        }
    }

    public static class EdgeComparator implements Comparator<Edge> {

        @Override
        public int compare(Edge o1, Edge o2) {
            return o1.weight - o2.weight;
        }

    }

    public static Set<Edge> kruskalMST(Graph graph) {
        UnionFind unionFind = new UnionFind();
        unionFind.makeSets(graph.nodes.values());
        PriorityQueue<Edge> priorityQueue = new PriorityQueue<>(new EdgeComparator());
        for (Edge edge : graph.edges) {
            priorityQueue.add(edge);
        }
        Set<Edge> result = new HashSet<>();
        while (!priorityQueue.isEmpty()) {
            Edge edge = priorityQueue.poll();
            if (!unionFind.isSameSet(edge.from, edge.to)) {
                result.add(edge);
                unionFind.union(edge.from, edge.to);
            }
        }
        return result;
    }
}

题目:Prim

package basic_class_05;

import java.util.Comparator;
import java.util.HashSet;
import java.util.PriorityQueue;
import java.util.Set;

// undirected graph only
public class Code_06_Prim {

    public static class EdgeComparator implements Comparator<Edge> {

        @Override
        public int compare(Edge o1, Edge o2) {
            return o1.weight - o2.weight;
        }

    }

    public static Set<Edge> primMST(Graph graph) {
        PriorityQueue<Edge> priorityQueue = new PriorityQueue<>(new EdgeComparator());
        HashSet<Node> set = new HashSet<>();
        Set<Edge> result = new HashSet<>();
        for (Node node : graph.nodes.values()) {
            if (!set.contains(node)) {
                set.add(node);
                for (Edge edge : node.edges) {
                    priorityQueue.add(edge);
                }
                while (!priorityQueue.isEmpty()) {
                    Edge edge = priorityQueue.poll();
                    Node toNode = edge.to;
                    if (!set.contains(toNode)) {
                        set.add(toNode);
                        result.add(edge);
                        for (Edge nextEdge : node.edges) {
                            priorityQueue.add(nextEdge);
                        }
                    }
                }
            }
        }
        return result;
    }

}

Dijkstra算法

package basic_class_05;

    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.Map.Entry;

    // no negative weight
    public class Code_07_Dijkstra {

        public static HashMap<Node, Integer> dijkstra1(Node head) {
            HashMap<Node, Integer> distanceMap = new HashMap<>();
            distanceMap.put(head, 0);
            HashSet<Node> selectedNodes = new HashSet<>();

            Node minNode = getMinDistanceAndUnselectedNode(distanceMap, selectedNodes);
            while (minNode != null) {
                int distance = distanceMap.get(minNode);
                for (Edge edge : minNode.edges) {
                    Node toNode = edge.to;
                    if (!distanceMap.containsKey(toNode)) {
                        distanceMap.put(toNode, distance + edge.weight);
                    }
                    distanceMap.put(edge.to, Math.min(distanceMap.get(toNode), distance + edge.weight));
                }
                selectedNodes.add(minNode);
                minNode = getMinDistanceAndUnselectedNode(distanceMap, selectedNodes);
            }
            return distanceMap;
        }

        public static Node getMinDistanceAndUnselectedNode(HashMap<Node, Integer> distanceMap, HashSet<Node> touchedNodes) {
            Node minNode = null;
            int minDistance = Integer.MAX_VALUE;
            for (Entry<Node, Integer> entry : distanceMap.entrySet()) {
                Node node = entry.getKey();
                int distance = entry.getValue();
                if (!touchedNodes.contains(node) && distance < minDistance) {
                    minNode = node;
                    minDistance = distance;
                }
            }
            return minNode;
        }

        public static class NodeRecord {
            public Node node;
            public int distance;

            public NodeRecord(Node node, int distance) {
                this.node = node;
                this.distance = distance;
            }
        }

        public static class NodeHeap {
            private Node[] nodes;
            private HashMap<Node, Integer> heapIndexMap;
            private HashMap<Node, Integer> distanceMap;
            private int size;

            public NodeHeap(int size) {
                nodes = new Node[size];
                heapIndexMap = new HashMap<>();
                distanceMap = new HashMap<>();
                this.size = 0;
            }

            public boolean isEmpty() {
                return size == 0;
            }

            public void addOrUpdateOrIgnore(Node node, int distance) {
                if (inHeap(node)) {
                    distanceMap.put(node, Math.min(distanceMap.get(node), distance));
                    insertHeapify(node, heapIndexMap.get(node));
                }
                if (!isEntered(node)) {
                    nodes[size] = node;
                    heapIndexMap.put(node, size);
                    distanceMap.put(node, distance);
                    insertHeapify(node, size++);
                }
            }

            public NodeRecord pop() {
                NodeRecord nodeRecord = new NodeRecord(nodes[0], distanceMap.get(nodes[0]));
                swap(0, size - 1);
                heapIndexMap.put(nodes[size - 1], -1);
                distanceMap.remove(nodes[size - 1]);
                nodes[size - 1] = null;
                heapify(0, --size);
                return nodeRecord;
            }

            private void insertHeapify(Node node, int index) {
                while (distanceMap.get(nodes[index]) < distanceMap.get(nodes[(index - 1) / 2])) {
                    swap(index, (index - 1) / 2);
                    index = (index - 1) / 2;
                }
            }

            private void heapify(int index, int size) {
                int left = index * 2 + 1;
                while (left < size) {
                    int smallest = left + 1 < size && distanceMap.get(nodes[left + 1]) < distanceMap.get(nodes[left])
                            ? left + 1 : left;
                    smallest = distanceMap.get(nodes[smallest]) < distanceMap.get(nodes[index]) ? smallest : index;
                    if (smallest == index) {
                        break;
                    }
                    swap(smallest, index);
                    index = smallest;
                    left = index * 2 + 1;
                }
            }

            private boolean isEntered(Node node) {
                return heapIndexMap.containsKey(node);
            }

            private boolean inHeap(Node node) {
                return isEntered(node) && heapIndexMap.get(node) != -1;
            }

            private void swap(int index1, int index2) {
                heapIndexMap.put(nodes[index1], index2);
                heapIndexMap.put(nodes[index2], index1);
                Node tmp = nodes[index1];
                nodes[index1] = nodes[index2];
                nodes[index2] = tmp;
            }
        }

        public static HashMap<Node, Integer> dijkstra2(Node head, int size) {
            NodeHeap nodeHeap = new NodeHeap(size);
            nodeHeap.addOrUpdateOrIgnore(head, 0);
            HashMap<Node, Integer> result = new HashMap<>();
            while (!nodeHeap.isEmpty()) {
                NodeRecord record = nodeHeap.pop();
                Node cur = record.node;
                int distance = record.distance;
                for (Edge edge : cur.edges) {
                    nodeHeap.addOrUpdateOrIgnore(edge.to, edge.weight + distance);
                }
                result.put(cur, distance);
            }
            return result;
        }

    }

相关文章

  • 邻接表|DFS|BFS

    结构定义 创建无向图 输出 DFS BFS

  • 无向图DFS和BFS

    基本结构 DFS深度优先遍历 BFS广度优先遍历 符号图

  • 图的结构 BFS DFS

    题目:BFS 一个队列,一个set集合 题目:DFS 题目:Kruskal算法 题目:Prim Dijkstra算法

  • 用Python实现树的BFS与DFS

    一、BFS与DFS简介 在理解动态规划、BFS和DFS一文中,已经集合具体例子,介绍了图的BFS与DFS。但是比较...

  • 无向图 图的表示方法:邻接表 dfs和bfs的区别:dfs是用栈,bfs用队列 有向图 有向无环图(DAG): 不...

  • BFS / DFS 典型例题

    图的BFS: leetcode:1162 地图分析leetcode:542 01矩阵 树的BFS: 图的DFS: ...

  • BFS和DFS随笔

    BFS和DFS BFS和DFS视频讲解-正月点灯笼 BFS核心点是用队列存放当前搜索的点 用在有环图的时候需要存放...

  • 图的桥和割点

    内容概要: 图中的桥 图的DFS遍历树和BFS遍历树及其与寻桥算法的关系 图的割点 DFS和BFS的对比小结 桥(...

  • Binary Tree(2)

    BFS vs DFS for Binary Tree What are BFS and DFS for Binar...

  • 图 | DFS & BFS

    图的基本概念 图论的一些概念和细节一开始是上算法的时候看助教大大的教程学的。放个链接,这里是️不堪回首胆战心惊的算...

网友评论

      本文标题:图的结构 BFS DFS

      本文链接:https://www.haomeiwen.com/subject/wurwpftx.html