標籤:style blog ar color sp for java 資料 div
圖的應用-搜尋的實現
圖的搜尋主要包括兩種1個是深度優先搜尋,一個是廣度優先搜尋。深度優先搜尋顧名思義就是一直遠離源搜尋點,搜尋下去,深度優先搜尋的機制是有棧來實現的,廣度優先搜尋演算法是由隊列來實現的,正因為實現的機制不同,所以搜尋的方式也不同。
首先講解一下深度優先搜尋方法,首先找一個起始點,然後做三件事:1:首先訪問該頂點,2:然後把該點放入到棧中,以便記住它3:標記該點這樣就不會再訪問該點了。下面可以訪問任何與A相連的頂點,只要還沒有訪問過它。
規則1:訪問一個未訪問的頂點,標記它把它加入到棧中。
規則2:當不能執行規則1的時候,如果棧不空,就從棧中彈出一個頂點。
規則3:就是規則1和規則2都不能執行的時候,這個搜尋就結束了。
深度優先搜尋的關鍵在於如何找到與某一個頂點鄰接沒有訪問過的點,鄰接矩陣是關鍵,找到指定頂點所在的行,從第一列開始向後尋找值為1的列,列號是鄰接頂點的號碼,檢查這個頂點是否未訪問過,如果是這樣就直接存取下一個頂點,如果該行沒有頂點即等於1且未訪問過的,那麼與指定點相串連的頂點全部訪問過了。
代碼:
//返回沒有訪問過的頂點 public int getAdjUnvisitedVertex(int v) { for(int j = 0;j<=currentVertexs;j++) { if(adjMat[v][j] == 1&& vertexs[j].wasVisited == false) { return j; } } return -1; }
深度優先演算法的實現:
public void dfs() { //從第0個點開始 vertexs[0].wasVisited=true; //列印該頂點 displayVertex(0); myStack.push(0); while(!myStack.isEmpty()) { int v = getAdjUnvisitedVertex(myStack.peek()); if(v == -1) { myStack.pop(); }else{ //跟第一個點處理相同 vertexs[v].wasVisited = true; //列印該點 displayVertex(v); //入棧 myStack.push(v); } } //棧空了就結束 for(int j=0;j<currentVertexs;j++) { //所有的頂點標誌位置為false結束 vertexs[j].wasVisited = false; } }
下面講解廣度優先搜尋:
深度優先搜尋演算法表現盡量的遠離起始點,廣度則不是,盡量的靠近起始點。首先訪問起始點的鄰接點,然後再訪問較遠的地區。
規則1:訪問下一個未來訪問的鄰接點(如果存在)這個頂點必須是當前頂點的鄰接點,標記它並且把它插入到隊列中。
規則2:如果因為已經沒有未訪問過的頂點不能執行規則1,那麼從隊列的頭取出一個頂點(如果存在),並且使它成為當前的頂點。
規則3:如果隊列為空白不能執行規則2,就搜尋結束。
代碼:
import java.util.LinkedList;import java.util.Queue;import java.util.Stack;public class GuDuGraph { /** * 這個類是表示資料結構的圖 */ private final int max_vertex = 20;//最大的點的數量 private Vertex[]vertexs ;//頂點的數組 private int adjMat[][];//表示一個鄰接矩陣 private int currentVertexs;//當前頂點的實際的數量。 private Queue<Integer>queue; public GuDuGraph() { vertexs = new Vertex[max_vertex]; adjMat = new int [max_vertex][max_vertex]; currentVertexs = 0;//當前的數量0個 //初始化鄰接矩陣 for(int i = 0;i<max_vertex;i++) { for(int j=0;j<max_vertex;j++) { adjMat[i][j] = 0; } } queue = new LinkedList<Integer>(); } //定義圖的操作類 //添加頂點的方法 public void addVertex(char lab) { vertexs[currentVertexs++] = new Vertex(lab); } //添加邊的方法 public void addEdge(int start,int end) { adjMat[start][end] = 1; adjMat[end][start] = 1; } //為了輸出的效果 public void printGraph() { for(int i=0;i<max_vertex;i++) { for(int j=0;j<max_vertex;j++) { System.out.print(adjMat[i][j]+" "); } System.out.println(); } } //列印頂點的方法的實現 public void displayVertex(int v) { System.out.print(vertexs[v].label); } //返回沒有訪問過的頂點 public int getAdjUnvisitedVertex(int v) { for(int j = 0;j<=currentVertexs;j++) { if(adjMat[v][j] == 1&& vertexs[j].wasVisited == false) { return j; } } return -1; } public void bfs() { //從第0個點開始 vertexs[0].wasVisited=true; //列印該頂點 displayVertex(0); queue.add(0); while(!queue.isEmpty()) { int v2 = getAdjUnvisitedVertex(queue.peek()); if(v2 == -1) { queue.poll(); }else{ //跟第一個點處理相同 vertexs[v2].wasVisited = true; //列印該點 displayVertex(v2); //入棧 queue.add(v2); } } //棧空了就結束 for(int j=0;j<currentVertexs;j++) { //所有的頂點標誌位置為false結束 vertexs[j].wasVisited = false; } } }
圖的應用-搜尋的實現