concept
- vertex
- Edge edge
- Route
- Undirected graph: the connection between vertices has no direction
- Directed graph: the connection between vertices has direction
- Weighted Map: Edges with weights, also called networks
Graph representation
Two-dimensional array representation (adjacency matrix); chain table representation (adjacency table)
Adjacency Matrix: A matrix representing the adjacent relationship between vertices in a graph. For a graph with n vertices, the matrix is 1 represented by row and col...N points
Contiguity table:
- Adjacency matrix needs to allocate space with n edges for each vertex. In fact, many edges do not exist, which will cause a certain loss of space.
- The implementation of adjacency table only concerns the existing edges, not the nonexistent edges, so there is no space waste. The adjacency table is composed of an array + a chain table
Code implementation diagram structure
- Store vertex String ArrayList
- Save Matrix: Two-dimensional array int/[]/[] edges
package graph; import java.util.ArrayList; import java.util.Arrays; public class GraphDemo01 { private ArrayList<String> vertexList; // store vertex private int[][] edges; // preliminary matrix corresponding to graph private int numOfEdges; // # of edges public static void main(String[] args) { int n = 5; String VertexValue[] = {"A","B","C","D","E"}; // create graph object GraphDemo01 graph = new GraphDemo01(n); // add vertex for(String value:VertexValue){ graph.insertVertex(value); } // add edges graph.insertEdge(0,1,1); graph.insertEdge(0,2,1); graph.insertEdge(1,2,1); graph.insertEdge(1,3,1); graph.insertEdge(1,4,1); // show graph.showGrapgh(); } // constructor public GraphDemo01(int n){ // initialize vertex and vertexList edges = new int[n][n]; vertexList = new ArrayList<String>(n); numOfEdges = 0; } // commonly used methods in graph // return nums of vertex public int getNumOfVertex(){ return vertexList.size(); } // get nums of edges public int getNumOfEdges(){ return numOfEdges; } // return info of vertex i, eg: 0-"A" 1-"B" 2-"C" public String getValueByIndex(int i){ return vertexList.get(i); } // return weight between v1 and v2 public int getWeight(int v1,int v2){ return edges[v1][v2]; } // show the matrix corresponding the graph public void showGrapgh(){ for(int[] link:edges){ System.out.println(Arrays.toString(link)); } } // insert vertex public void insertVertex(String vertex){ vertexList.add(vertex); } // add edges /** * add edges * @param v1 index of the first vertex * @param v2 index of the second vertex * @param weight weight between v1 and v2 */ public void insertEdge(int v1, int v2, int weight){ edges[v1][v2] = weight; edges[v2][v1] = weight; numOfEdges++; } }Graph Traversal
Graph traversal, that is, access to nodes
Strategy: Depth-first traversal; Width-first traversal
dfs
Depth First Search
- Starting from the initial access node, the initial access node may have multiple adjacent nodes. The depth-first traversal strategy is to first access the first adjacent node, and then use this accessed adjacent node as the initial node to access its first adjacent node.It can be understood that each time the current node is visited, the first adjacent node of the current node is visited first
- Mining in depth longitudinally rather than horizontally accessing all adjacent nodes of a node
- Depth-first search is a recursive process
Algorithmic steps:
- Access the initial node v and mark the node v as visited
- Find the first adjacent node w of node v
- If w exists, continue execution 4, if w does not exist, go back to step 1, and continue from the next node of v
- If W is not accessed, do depth-first traversal recursion on w (that is, treat w as another v and proceed to step 1, 2, 3)
- Find the next adjacent node of the w-adjacent node of node v and go to step 3
Code
// constructor public GraphDemo01(int n){ // initialize vertex and vertexList edges = new int[n][n]; vertexList = new ArrayList<String>(n); numOfEdges = 0; isVisited = new boolean[5]; } /** * get the index of the first preliminary node * @param index * @return if exists, return index, or return -1 */ public int getFirstNeighbor(int index){ for(int j = 0; j<vertexList.size();j++){ if(edges[index][j]>0){ return j; } } return -1; } // get next neighbor node according to index of previous neighbor node public int getNextNeighbor(int v1,int v2){ for(int j = v2+1;j<vertexList.size();j++){ if(edges[v1][j]>0){ return j; } } return -1; } // dfs // At first: i is 0 private void dfs(boolean[] isVisited,int i){ // visit (output) this node System.out.println(getValueByIndex(i)+" -> "); // set status of this node to visited isVisited[i] = true; // the first neighbor of i int w = getFirstNeighbor(i); while(w!=-1){ if(!isVisited[w]){ dfs(isVisited,w); } // if w has been visited w = getNextNeighbor(i,w); } } // override dfs, traverse all node and do dfs public void dfs(){ for (int i = 0; i < getNumOfVertex(); i++) { if(!isVisited[i]){ dfs(isVisited,i); } } }
// main function // test dfs System.out.println("dfs"); graph.dfs();
breadth-first search
Broad First Search
Similar to a hierarchical search process, a queue is needed to preserve the order of visited nodes in order to access their adjacent nodes
Algorithmic steps:
- Access the initial node v and mark that node v has been accessed
- Node v Queued
- Continue execution when the queue is not empty or the algorithm ends
- Out of queue, get queue head node u
- Find the first adjacent node w of node u
- If the adjacent node w of node u does not exist, go to step 3; otherwise, perform the following three steps
- If node w is not accessed, access node w and mark it as accessed
- Node w Queued
- Find the next adjacent node w following the w-adjacent node of node u and go to step 6
Code
// bfs for one node (for loop for all nodes) private void bfs(boolean[] isVisited,int i){ int u; // index of queue head int w; // index of preliminary node // queue: record order of node access LinkedList queue = new LinkedList(); // visit this node, output it System.out.println(getValueByIndex(i)+" -> "); // mark as "visited" isVisited[i] = true; // add this node into queue(first in first out) queue.addLast(i); while(!queue.isEmpty()){ // pick up the head of queue u = (Integer) queue.removeFirst(); // get the index of the first preliminary node w = getFirstNeighbor(u); while(w!=-1){ // find it // whether it is visited if(!isVisited[w]){ System.out.println(getValueByIndex(w)+" -> "); // mark it as visited isVisited[w] = true; // in queue queue.addLast(w); } // visited already // take u as the previous node,find next preliminary node of w w = getNextNeighbor(u,w); } } } // traverse all node, do bfs public void bfs(){ for (int i = 0; i < getNumOfVertex(); i++) { if(!isVisited[i]){ bfs(isVisited,i); } } }
// main methods // test bfs System.out.println("bfs"); graph.bfs();