深度優先搜索
深度優先搜索,我們以無向圖為例。
圖的深度優先搜索(Depth First Search),和樹的先序遍歷比較類似。
它的思想:假設初始狀態是圖中所有頂點均未被訪問,則從某個頂點v出發,首先訪問該頂點,然后依次從它的各個未被訪問的鄰接點出發深度優先搜索遍歷圖,直至圖中所有和v有路徑相通的頂點都被訪問到。 若此時尚有其他頂點未被訪問到,則另選一個未被訪問的頂點作起始點,重復上述過程,直至圖中所有頂點都被訪問到為止。
顯然,深度優先搜索是一個遞歸的過程。
鄰接矩陣DFS
package com.darrenchan.graph; public class MatrixNDG { int size;//圖頂點個數 char[] vertexs;//圖頂點名稱 int[][] matrix;//圖關系矩陣 public MatrixNDG(char[] vertexs, char[][] edges){ size=vertexs.length; matrix=new int[size][size];//設定圖關系矩陣大小 this.vertexs=vertexs; for(char[] c:edges){//設置矩陣值 int p1 = getPosition(c[0]);//根據頂點名稱確定對應矩陣下標 int p2 = getPosition(c[1]); matrix[p1][p2] = 1;//無向圖,在兩個對稱位置存儲 matrix[p2][p1] = 1; } } //圖的遍歷輸出 public void print(){ for(int[] i:matrix){ for(int j:i){ System.out.print(j+" "); } System.out.println(); } } //根據頂點名稱獲取對應的矩陣下標 private int getPosition(char ch) { for(int i=0; i<vertexs.length; i++) if(vertexs[i]==ch) return i; return -1; } public static void main(String[] args) { char[] vexs = {'A', 'B', 'C', 'D', 'E', 'F', 'G','H','I','J','K'}; char[][] edges = new char[][]{ {'A', 'C'}, {'A', 'D'}, {'A', 'F'}, {'B', 'C'}, {'C', 'D'}, {'E', 'G'}, {'D', 'G'}, {'I', 'J'}, {'J', 'G'}, {'E', 'H'}, {'H', 'K'}}; MatrixNDG pG = new MatrixNDG(vexs, edges); pG.print(); pG.DFS(); } public void DFS(){ boolean[] beTraversed=new boolean[size]; for(int i=0;i<size;i++){ beTraversed[i]=false; } System.out.print(vertexs[0] + " "); beTraversed[0]=true; DFS(0,0,beTraversed); } private void DFS(int x,int y,boolean[] beTraversed){ while(y<=size-1){ if(matrix[x][y]!=0&beTraversed[y]==false){ System.out.print(vertexs[y] + " "); beTraversed[y]=true; DFS(y,0,beTraversed); } y++; } } }

鄰接表DFS
package com.darrenchan.graph; public class ListNDG { Vertex[] vertexLists;//鄰接表數組 int size; class Vertex{//鄰接表節點類,單鏈表數據結構 char ch; Vertex next; Vertex(char ch){//初始化方法 this.ch=ch; } void add(char ch){//加到鏈表尾 Vertex node=this; while(node.next!=null){ node=node.next; } node.next=new Vertex(ch); } } public ListNDG(char[] vertexs,char[][] edges){ size=vertexs.length; this.vertexLists=new Vertex[size];//確定鄰接表大小 //設置鄰接表每一個節點 for(int i=0;i<size;i++){ this.vertexLists[i]=new Vertex(vertexs[i]); } //存儲邊信息 for(char[] c:edges){ int p1=getPosition(c[0]); vertexLists[p1].add(c[1]); int p2=getPosition(c[1]); vertexLists[p2].add(c[0]); } } //跟據頂點名稱獲取鏈表下標 private int getPosition(char ch) { for(int i=0; i<size; i++) if(vertexLists[i].ch==ch) return i; return -1; } //遍歷輸出鄰接表 public void print(){ for(int i=0;i<size;i++){ Vertex temp=vertexLists[i]; while(temp!=null){ System.out.print(temp.ch+" "); temp=temp.next; } System.out.println(); } } public static void main(String[] args){ char[] vexs = {'A', 'B', 'C', 'D', 'E', 'F', 'G','H','I','J','K'}; char[][] edges = new char[][]{ {'A', 'C'}, {'A', 'D'}, {'A', 'F'}, {'B', 'C'}, {'C', 'D'}, {'E', 'G'}, {'D', 'G'}, {'I', 'J'}, {'J', 'G'}, {'E', 'H'}, {'H', 'K'}}; ListNDG pG = new ListNDG(vexs, edges); pG.print(); // 打印圖 pG.DFS(); } public void DFS(){ boolean[] beTraversed=new boolean[size]; for(int i=0;i<size;i++){ beTraversed[i]=false; } for (int i = 0; i < size; i++) { if (!beTraversed[i]) DFS(beTraversed,vertexLists[i]); } } public void DFS(boolean[] beTraversed,Vertex temp){ System.out.print(temp.ch + " "); beTraversed[getPosition(temp.ch)]=true; while(temp!=null){ if(beTraversed[getPosition(temp.ch)]==false){ DFS(beTraversed,vertexLists[getPosition(temp.ch)]); } temp=temp.next; } } }
廣度優先搜索
廣度優先搜索,我們以有向圖為例。
廣度優先搜索算法(Breadth First Search),又稱為”寬度優先搜索”或”橫向優先搜索”,簡稱BFS。
它的思想是:從圖中某頂點v出發,在訪問了v之后依次訪問v的各個未曾訪問過的鄰接點,然后分別從這些鄰接點出發依次訪問它們的鄰接點,並使得“先被訪問的頂點的鄰接點先於后被訪問的頂點的鄰接點被訪問,直至圖中所有已被訪問的頂點的鄰接點都被訪問到。如果此時圖中尚有頂點未被訪問,則需要另選一個未曾被訪問過的頂點作為新的起始點,重復上述過程,直至圖中所有頂點都被訪問到為止。
換句話說,廣度優先搜索遍歷圖的過程是以v為起點,由近至遠,依次訪問和v有路徑相通且路徑長度為1,2…的頂點。
鄰接矩陣BFS
package com.darrenchan.graph; import java.util.LinkedList; public class MatrixDG { int size; char[] vertexs; int[][] matrix; public MatrixDG(char[] vertexs,char[][] edges){ size=vertexs.length; matrix=new int[size][size]; this.vertexs=vertexs; //和鄰接矩陣無向圖差別僅僅在這里 for(char[] c:edges){ int p1 = getPosition(c[0]); int p2 = getPosition(c[1]); matrix[p1][p2] = 1; } } public void print(){ for(int[] i:matrix){ for(int j:i){ System.out.print(j+" "); } System.out.println(); } } private int getPosition(char ch) { for(int i=0; i<vertexs.length; i++) if(vertexs[i]==ch) return i; return -1; } public static void main(String[] args) { char[] vexs = {'A', 'B', 'C', 'D', 'E', 'F', 'G','H','I','J','K'}; char[][] edges = new char[][]{ {'A', 'C'}, {'A', 'D'}, {'A', 'F'}, {'B', 'C'}, {'C', 'D'}, {'E', 'G'}, {'D', 'G'}, {'I', 'J'}, {'J', 'G'}, {'E', 'H'}, {'H', 'K'}}; MatrixDG pG = new MatrixDG(vexs, edges); pG.print(); pG.BFS(); } public void BFS(){ boolean[] beTraversed=new boolean[size]; for(int i=0;i<size;i++){ beTraversed[i]=false; } System.out.print(vertexs[0] + " "); beTraversed[0]=true; BFS(0,beTraversed); } public void BFS(int x,boolean[] beTraversed){ LinkedList<Character> list=new LinkedList<Character>(); int y=0; while(y<=size-1){ if(matrix[x][y]!=0&beTraversed[y]==false){ System.out.print(vertexs[y] + " "); beTraversed[y]=true; list.add(vertexs[y]); } y++; } while(!list.isEmpty()){ char ch=list.pop(); int t=getPosition(ch); BFS(t,beTraversed); } } }
鄰接表BFS
package com.darrenchan.graph; import java.util.LinkedList; public class ListDG { Vertex[] vertexLists; int size; class Vertex{ char ch; Vertex next; Vertex(char ch){ this.ch=ch; } void add(char ch){ Vertex node=this; while(node.next!=null){ node=node.next; } node.next=new Vertex(ch); } } public ListDG(char[] vertexs,char[][] edges){ size=vertexs.length; this.vertexLists=new Vertex[size]; //設置鄰接表每一個節點 for(int i=0;i<size;i++){ this.vertexLists[i]=new Vertex(vertexs[i]); } //存儲邊信息 //只有這里和無序圖不同 for(char[] c:edges){ int p=getPosition(c[0]); vertexLists[p].add(c[1]); } } private int getPosition(char ch) { for(int i=0; i<size; i++) if(vertexLists[i].ch==ch) return i; return -1; } public void print(){ for(int i=0;i<size;i++){ Vertex temp=vertexLists[i]; while(temp!=null){ System.out.print(temp.ch+" "); temp=temp.next; } System.out.println(); } } public static void main(String[] args){ char[] vexs = {'A', 'B', 'C', 'D', 'E', 'F', 'G','H','I','J','K'}; char[][] edges = new char[][]{ {'A', 'C'}, {'A', 'D'}, {'A', 'F'}, {'B', 'C'}, {'C', 'D'}, {'E', 'G'}, {'D', 'G'}, {'I', 'J'}, {'J', 'G'}, {'E', 'H'}, {'H', 'K'}}; ListDG pG = new ListDG(vexs, edges); pG.print(); // 打印圖 pG.BFS(); } public void BFS(){ boolean[] isTraversed=new boolean[size]; for(int i=0;i<size;i++){ isTraversed[i]=false; } System.out.print(vertexLists[0].ch + " "); isTraversed[0]=true; BFS(0,isTraversed); } public void BFS(int x,boolean[] isTraversed){ Vertex temp=vertexLists[x]; LinkedList<Vertex> list=new LinkedList<Vertex>(); while(temp!=null){ if(isTraversed[getPosition(temp.ch)]==false){ System.out.print(temp.ch + " "); isTraversed[getPosition(temp.ch)]=true; list.add(temp); } temp=temp.next; } while(!list.isEmpty()){ Vertex v=list.pop(); int t=getPosition(v.ch); BFS(t,isTraversed); } } }