圖:G=(V,E),V表明節點,E表明邊。java
圖有兩種表示方法:鄰接鏈表和鄰接矩陣算法
鄰接鏈表由於在表示稀疏圖(邊的條數|E|遠遠小於|V|²的圖)時很是緊湊而成爲一般的選擇。ide
若是須要快速判斷任意兩個節點之間是否有邊相連,可能也須要使用鄰接矩陣表示法。測試
鄰接鏈表表示法的魯棒性很高,能夠對其進行簡單修改來支持許多其餘的圖變種。ui
鄰接鏈表的一個潛在缺陷是沒法快速判斷一條邊是不是圖中地一條邊。鄰接矩陣則克服了這個缺陷,但付出的代價是更大的存儲空間消耗。this
——摘自《算法導論》spa
圖的搜索算法即:廣度優先搜索和深度優先搜索3d
相信這兩種搜索算法的基本概念根據名字就可窺得一二,很少說,直接上例子。code
如上有向圖,建立三個類:blog
如下是構建好的圖信息以及點遍歷結果。
如下是Java源碼。BFS輔以隊列以非遞歸方法完成,DFS以遞歸方法完成。註釋得很詳細,我就很少解釋了@(^<>^)@。
1 import java.util.ArrayList; 2 import java.util.Iterator; 3 import java.util.LinkedList; 4 import java.util.Queue; 5 6 class Graph{ 7 ArrayList<Vertex> vertexs=new ArrayList<Vertex>(); 8 ArrayList<Edge> edges=new ArrayList<Edge>(); 9 10 public void addVertex(Vertex vertex) { 11 vertexs.add(vertex); 12 } 13 14 public void addEdge(Edge edge) { 15 edges.add(edge); 16 } 17 } 18 19 //頂點類 20 class Vertex{ 21 String name; 22 boolean visited=false; //標記該點是否被查看-廣度優先專用 23 boolean visited2=false; //標記該點是否被查看-深度優先專用 24 25 public Vertex(String name) { 26 this.name=name; 27 } 28 29 @Override 30 public String toString() { 31 return "[" + name + "]"; 32 } 33 } 34 //邊類 有向圖 35 class Edge{ 36 Vertex start; 37 Vertex end; 38 39 public Edge(Vertex start,Vertex end) { 40 this.start=start; 41 this.end=end; 42 } 43 44 @Override 45 public String toString() { 46 return "(" + start + "," + end + ")"; 47 } 48 } 49 50 public class SearchGraph { 51 //廣度優先 非遞歸 52 static void BFS(Graph graph) { 53 ArrayList<Vertex> vertexs=graph.vertexs; 54 ArrayList<Edge> edges=graph.edges; 55 Queue<Vertex> queue = new LinkedList<Vertex>(); //建立隊列 56 57 queue.add(vertexs.get(0)); //頂節點放入隊列 58 vertexs.get(0).visited=true; //頂節點設爲已閱 59 System.out.print(vertexs.get(0)); 60 61 while(!queue.isEmpty()) { 62 Vertex vertex=queue.remove(); 63 for(Edge edge:edges) { 64 if(edge.start.equals(vertex)&&edge.end.visited==false) { 65 queue.add(edge.end); 66 edge.end.visited=true; 67 System.out.print(edge.end); 68 } 69 } 70 } 71 72 } 73 74 //深度優先 遞歸 75 static void DFS(Graph graph,Vertex vertex) { //參數:圖、點信息 76 System.out.print(vertex); 77 vertex.visited2=true; 78 79 for(Edge edge:graph.edges) { 80 if(edge.start.equals(vertex)&&edge.end.visited2==false) { 81 DFS(graph,edge.end); 82 } 83 } 84 } 85 86 public static void main(String[] args) { 87 // TODO Auto-generated method stub 88 89 //構造有向圖 90 Graph graph=new Graph(); 91 Vertex v0=new Vertex("v0"); 92 Vertex v1=new Vertex("v1"); 93 Vertex v2=new Vertex("v2"); 94 Vertex v3=new Vertex("v3"); 95 Vertex v4=new Vertex("v4"); 96 Vertex v5=new Vertex("v5"); 97 Vertex v6=new Vertex("v6"); 98 graph.addVertex(v0); 99 graph.addVertex(v1); 100 graph.addVertex(v2); 101 graph.addVertex(v3); 102 graph.addVertex(v4); 103 graph.addVertex(v5); 104 graph.addVertex(v6); 105 Edge e0=new Edge(v0,v1); 106 Edge e1=new Edge(v0,v2); 107 Edge e2=new Edge(v0,v3); 108 Edge e3=new Edge(v1,v4); 109 Edge e4=new Edge(v1,v5); 110 Edge e5=new Edge(v2,v4); 111 Edge e6=new Edge(v3,v5); 112 Edge e7=new Edge(v4,v6); 113 Edge e8=new Edge(v5,v6); 114 graph.addEdge(e0); 115 graph.addEdge(e1); 116 graph.addEdge(e2); 117 graph.addEdge(e3); 118 graph.addEdge(e4); 119 graph.addEdge(e5); 120 graph.addEdge(e6); 121 graph.addEdge(e7); 122 graph.addEdge(e8); 123 //構造有向圖 124 125 //測試圖建立結果 126 ArrayList<Vertex> vertexs=graph.vertexs; 127 ArrayList<Edge> edges=graph.edges; 128 Iterator iVertex=vertexs.iterator(); 129 Iterator iEdge=edges.iterator(); 130 System.out.println("點集合:"); 131 while(iVertex.hasNext()) { 132 System.out.print(iVertex.next()); 133 } 134 System.out.println(); 135 System.out.println("邊集合:"); 136 while(iEdge.hasNext()) { 137 System.out.print(iEdge.next()); 138 } 139 //測試圖建立結果 140 141 //遍歷 142 System.out.println(""); 143 System.out.println("廣度優先遍歷:"); 144 BFS(graph); 145 System.out.println(""); 146 System.out.println("深度優先遍歷:"); 147 DFS(graph,v0); 148 //遍歷 149 } 150 151 }