1. 程式人生 > >資料結構之圖的深度優先遍歷和廣度優先遍歷

資料結構之圖的深度優先遍歷和廣度優先遍歷

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