1, The storage method of the graph. If the graph is expressed, the graph is generated
1. Storage mode of drawing

Adjacency table

adjacency matrix
2. Expression of graph  point set, edge set, graph
 point set
public class Node { public int value; public int in; //Penetration public int out; //Out degree public ArrayList<Node> nexts; //The point of a direct neighbor diverged by him public ArrayList<Edge> edges; //What are my sides public Node(int value) { this.value = value; in = 0; out = 0; nexts = new ArrayList<>(); edges = new ArrayList<>(); } }
 Edge set
public class Edge { public int weight; //weight public Node from; //Directed edge from public Node to; //Directed edge to public Edge(int weight, Node from, Node to) { this.weight = weight; this.from = from; this.to = to; } }
 Figure: Point Set + edge set
public class Graph { public HashMap<Integer,Node> nodes; // The Integer here represents a marker value of the point that appears public HashSet<Edge> edges; //Edge set public Graph() { nodes = new HashMap<>(); edges = new HashSet<>(); } }
3. Generate diagram
 Two dimensional array, in which the first item of each array represents the weight and the second item represents from. The third item indicates to
public static Graph createGraph(Integer[][] matrix) { Graph graph = new Graph(); //The outermost loop represents several large loops, one onedimensional array and one edge at a time for (int i = 0; i < matrix.length; i++) { //The first item in each array represents the weight Integer weight = matrix[i][0]; //The second item indicates where from comes from Integer from = matrix[i][1]; //The third item indicates where to points Integer to = matrix[i][2]; //Judge this first. If not, skip it //If the from point does not exist in the point set of the graph, add the point to the point set //Update of point set of graph if (!graph.nodes.containsKey(from)) { graph.nodes.put(from, new Node(from));//join } //If the to point does not exist in the point set of the graph, add the point to the point set if (!graph.nodes.containsKey(to)) { graph.nodes.put(to, new Node(to));//join } //Get the from point and the to point Node fromNode = graph.nodes.get(from); Node toNode = graph.nodes.get(to); //The edges are established by these two points and weights Edge newEdge = new Edge(weight, fromNode, toNode); //Next, you need to update: points, edges and graphs should be updated //Update the nexts of fromnode's points, that is, the points of direct neighbors diverged by him fromNode.nexts.add(toNode); //Update the out of the fromnode point, that is, the out degree++ fromNode.out++; //Update the in of the point of tonode, that is, the penetration++ toNode.in++; //Update the edges of fromnode, that is, update the edges belonging to fromnode. This is to add a newly created edge fromNode.edges.add(newEdge); //Graph update, add one more edge set graph.edges.add(newEdge); } return graph; }
2, Traversal of Graphs
1. The width of the drawing shall first traverse the BFS
Using queues to implement
Enter the queue according to the width from the source node, and then pop up;
For each popup point, put all adjacent points of the node that have not entered the queue into the queue;
Until the queue is empty.
//Only point set type is needed public void BFS_(Node node){ if(node == null){ return; } //Prepare a queue to pop up by width in turn Queue<Node> queue = new LinkedList<>(); //Prepare a set set for de duplication to prevent a node from being added to the queue repeatedly, and finally output such errors repeatedly HashSet<Object> hashset = new HashSet<>(); //First add the source node to set and queue queue.add(node); hashset.add(node); //If the queue is not empty, it pops up one by one while(!queue.isEmpty()){ Node cur = queue.poll(); //Output on popup System.out.println(cur.value); //During each popup, all adjacent nodes of the popup node and nodes that have not entered the set are added to the queue. for(Node next:cur.nexts){ if(!hashset.contains(next)){ hashset.add(next); queue.add(next); } } } }
2. The depth of the graph first traverses DFS
Depth first traversal: starting from the initial access point, the initial access point may have multiple adjacent nodes. The strategy of depth first traversal is to first access the first adjacent node, and then use the accessed adjacent node as the initial access node to access its first adjacent node, That is, each time the current node is accessed, the first adjacent node of the current node will be accessed first. Similar to maze backtracking algorithm.
It can be seen that the current access strategy is to give priority to vertical mining, rather than horizontal access to all adjacent points of each node.
Using stack
A single wooden bridge goes to the black
Start from the source node, put each node into the stack according to the depth, and then pop up;
For each popup point, put the next adjacent point of the node that has not entered the stack into the stack;
Until the stack becomes empty.
public void DFS_(Node head){ HashSet<Node> hashset = new HashSet<>(); Stack<Node> stack = new Stack<>(); stack.push(node); hashset.add(node); System.out.println(node.value); while(!stack.isEmpty()){ Node cur = stack.pop(); for(Node next : cur.nexts){ if(!hashset.contains(next)){ //Note here that cur itself should also be added. Why? This gives a way back to prevent the next encounter from already in the set, so we have to find a way back, that is, backtracking and find other nodes. stack.push(cur); stack.push(next); hashset.add(next); System.out.println(next.value); //The reason for breaking is to let him not follow the width, but encounter a cycle of breaking this time, and let him continue down the new node. If he doesn't break, go to the width. break; } } } }
3, Topological sorting algorithm
Scope of application: it is required to have a directed graph, nodes with penetration of 0, and no ring
Topological sorting is actually to find a vertex with a degree of 0. This vertex is the first vertex sequence in topological sorting, mark and delete it, then reduce the degree of entry of the vertex adjacent to this vertex by 1, and then continue to find the vertex with a degree of 0 until all vertices have been marked and deleted or there are rings in the graph.
It can be seen from the above that the key is to find the vertex with penetration of 0.
Dependency completion sort
Directed graph
Using hash table
Find the points with penetration of 0 in turn, wipe them off in turn, and find them again in turn
public static List<Node> sortTopology(Graph graph){ //K of hashmap represents a node, and V represents the remaining penetration HashMap<Node, Integer> hashMap = new HashMap<>(); //Points with 0 remaining in the queue enter the queue Queue<Node> zeroInQueue = new LinkedList<>(); for (Node node : graph.nodes.values()){ hashMap.put(node, node.in); // Record the original penetration if (node.in == 0){ // The first batch of click in queues with a penetration of 0 zeroInQueue.add(node); } } //The topology sorting results are placed in the result List<Node> result = new ArrayList<>(); while ( !zeroInQueue.isEmpty()){ Node cur = zeroInQueue.poll(); result.add(cur); //Erase the influence of the current node for (Node next : cur.nexts){ hashMap.put(next,hashMap.get(next)  1); //Penetration is wiped if (hashMap.get(next) == 0){ zeroInQueue.add(next); } } } return result; }
4, Two algorithms of minimum spanning tree
Minimum spanning tree = = = guaranteed connectivity, minimum weight, for undirected graph
1.Kruskal algorithm
Scope of application: undirected graph is required
 Algorithm overview
Kruskal algorithm can be referred to as "edge addition method".
1) Always start from the edge with the smallest weight and investigate the edge with the larger weight in turn
2) The current edge either enters the collection of the minimum spanning tree or is discarded
3) If the current edge enters the set of the minimum spanning tree and does not form a ring, the current edge is selected
4) If the current edge enters the set of the minimum spanning tree to form a ring, do not use the current edge
5) After examining all the edges, the set of the minimum spanning tree is also obtained.
 sketch
1) To sort the edges, start from the smallest edge and judge whether there is an invisible ring (and search the set). If it is formed, it will not be added, and if it is not formed, it will be added
2) The judgment has an invisible ring, and all the initial points have a set respectively, which can be combined if possible.
3) Set query and merge  > join query set or common method
 Common method
public static class Mysets{ public HashMap<Node, List<Node>> setMap;//map of the collection of points public Mysets(List<Node> nodes){ for (Node cur: nodes){ List<Node> set = new ArrayList<>(); // Collection of each point set.add(cur); //The collection of each point is its own at the beginning setMap.put(cur,set); } } //Are from and to in the same set public boolean isSameSet(Node from, Node to){ List<Node> fromSet = setMap.get(from); //Collection from List<Node> toSet = setMap.get(to); //Set of to return fromSet == toSet; //Judge whether it is a set } //Synthesis of two sets public void union(Node from, Node to){ List<Node> fromSet = setMap.get(from); //Collection from List<Node> toSet = setMap.get(to); //Set of to for (Node toNode : toSet){ fromSet.add(toNode); setMap.put(toNode,fromSet); } } } //K algorithm public static Set<Edge> kruskalMST(Graph graph){ Mysets mysets = new Mysets((List<Node>) graph.nodes.values()); //At the bottom of the priority queue is the heap PriorityQueue<Edge> priorityQueue = new PriorityQueue<>(new Comparator<Edge>() { @Override public int compare(Edge o1, Edge o2) { return o1.weight  o2.weight; } }); for (Edge edge : graph.edges){ priorityQueue.add(edge); } Set<Edge> result = new HashSet<>(); while ( !priorityQueue.isEmpty()){ Edge edge = priorityQueue.poll(); if ( !mysets.isSameSet(edge.from, edge.to)){ result.add(edge); mysets.union(edge.from, edge.to); } } return result; }
 Use and query set
// UnionFind 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; }
2.Prim algorithm
Scope of application: undirected graph is required
Starting from the point, find the smallest edge, so as to get the point and start again and again
public static class EdgeComparator implements Comparator<Edge>{ @Override public int compare(Edge o1, Edge o2) { return o1.weight  o2.weight; } } public static Set<Edge> primSet(Graph graph){ //The unlocked edge enters the small root heap PriorityQueue<Edge> priorityQueue = new PriorityQueue<>(new EdgeComparator()); HashSet<Node> set = new HashSet<>(); //The unlocked points are placed in the set Set<Edge> result = new HashSet<>(); //Select the edges in turn and put them into result //The for loop handles the forest problem and generates the minimum spanning tree respectively. This is a special case. If the whole is a connected graph, there is no need to add it here for (Node node : graph.nodes.values()){//Pick any point //node is the starting point if ( !set.contains(node)){ set.add(node); for (Edge edge : node.edgs){ //By one point, unlock all connected edges priorityQueue.add(edge); } while ( !priorityQueue.isEmpty()){ Edge edge = priorityQueue.poll(); //The smallest of the popup unlocked edges Node toNode = edge.to; //Judge whether the toNode is a new point or not in the set if ( !set.contains(toNode)){ //No, just a new point, just join set.add(toNode); //I want this side result.add(edge); //The edges diverged from the toNode are put into the priority queue for (Edge nextEdge : toNode.edgs){ priorityQueue.add(nextEdge); } } } } } return result; }
5, Dijkstra algorithm
Scope of application: there are no edges with negative weight