資料結構之圖的深度優先遍歷和廣度優先遍歷
阿新 • • 發佈:2019-01-05
1.圖的簡單介紹
上圖就是一個圖(無線圖),由頂點和連線組成
圖可以分為無向圖和有向圖(這個又有出度、入度的概念)、網,一般來說圖有兩種常用的表示方式,鄰接矩陣(用二維陣列的形式表示)和鄰接表(主要是陣列+連結串列的形式表示),圖常用的遍歷方式有深度優先遍歷(DFS)和廣度優先遍歷(BFS)。
由於等會程式碼是用鄰接矩陣來實現DFS和BFS,這裡主要介紹一下鄰接矩陣的表示方法:兩個頂點相鄰,則在鄰接矩陣中值為1,否則為0,上邊圖的鄰接矩陣表示如下圖所示:
深度優先遍歷(DFS)思路是沿著一條路走到底,發現走到盡頭,再往回走,看剛剛還有哪些分支沒有走。
廣度優先遍歷(BFS)則是類似樹的層次遍歷,一個頂點先把與其相鄰的頂點遍歷,然後再遍歷其相鄰頂點的相鄰頂點。
具體可以去網易雲課堂看看小甲魚的《資料結構與演算法》,通俗易懂講解了DFS和BFS
下面主要是程式碼:
DFS的程式碼
import java.util.*; public class Main{public static void main(String[] args){
Scanner sc=new Scanner(System.in);
String line=sc.nextLine();
String[] element=line.split(" ");
int n=element.length;
int[][] matrix=new int[n][n];
for(int i=0;i<n;i++){
line=sc.nextLine();
String[] str=line.split(" ");
for(int j=0;j<n;j++){
matrix[i][j]=Integer.parseInt(str[j]);
}
}
int[] visited=new int[n];
ArrayList<Integer> list=new ArrayList<>();
DFS(matrix,0,0,visited,list);
for(int i:list){
System.out.print(element[i]+" ");
}
} private static void DFS(int[][] matrix, int i,int j, int[] visited,ArrayList<Integer> list) {
if(i==0&&j==0){ //如果是遍歷第一個點,將其加入訪問順序連結串列list
visited[0]=1;
list.add(0);
} int n=visited.length;
for(int x=i;x<n;x++){
for(int y=j;y<n;y++)
if(matrix[x][y]==1&&visited[y]==0){
visited[y]=1;
list.add(y); //前進時訪問的頂點
DFS(matrix,y,0,visited,list);
list.add(x); //回退時訪問的頂點
}
}
}
} 輸入: A B C D E F G H I
0 1 0 0 0 1 0 0 0
1 0 1 0 0 0 1 0 1
0 1 0 1 0 0 0 0 1
0 0 1 0 1 0 1 1 1
0 0 0 1 0 1 0 1 0
1 0 0 0 1 0 1 0 0
0 1 0 1 0 1 0 1 0
0 0 0 1 1 0 1 0 0
0 1 1 1 0 0 0 0 0 輸出: A B C D E F G H G F E D I D C B A BFS的程式碼: import java.util.*; public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
String line=sc.nextLine();
String[] element=line.split(" ");
int n=element.length;
int[][] matrix=new int[n][n];
for(int i=0;i<n;i++){
line=sc.nextLine();
String[] str=line.split(" ");
for(int j=0;j<n;j++){
matrix[i][j]=Integer.parseInt(str[j]);
}
}
int[] visited=new int[n];
LinkedList<Integer> record=new LinkedList<>(); //用於記錄上一頂點訪問過的所有相鄰頂點
ArrayList<Integer> list=new ArrayList<>(); //記錄遍歷的所有頂點
BFS(matrix,0,visited,record,list);
for(int current:list){
System.out.print(element[current]+" ");
}
} private static void BFS(int[][] matrix, int i, int[] visited,LinkedList<Integer> record, ArrayList<Integer> list) {
int count=0;
int n=visited.length;
for(int k=0;k<n;k++){ //如果全部頂點都被訪問過了,返回
if(visited[k]==1)count++;
}
if(count==n)return;
if(i==0){ //如果是遍歷的第一個頂點
visited[0]=1;
list.add(0);
}
for(int j=0;j<n;j++){ //遍歷當前頂點的所有相鄰頂點
if(matrix[i][j]==1&&visited[j]==0){
visited[j]=1;
list.add(j);
record.add(j);
}
}
BFS(matrix,record.removeFirst(),visited,record,list);
}
}
輸入:
A B C D E F G H I
0 1 0 0 0 1 0 0 0
1 0 1 0 0 0 1 0 1
0 1 0 1 0 0 0 0 1
0 0 1 0 1 0 1 1 1
0 0 0 1 0 1 0 1 0
1 0 0 0 1 0 1 0 0
0 1 0 1 0 1 0 1 0
0 0 0 1 1 0 1 0 0
0 1 1 1 0 0 0 0 0
輸出:
A B F C G I E D H