每日一題——圖的遍歷(BFS 和DFS)
阿新 • • 發佈:2018-12-14
- 題目描述
從鍵盤接收有向圖的頂點集,弧集,建立有向圖,並完成下列任務:
(1)計算結點的出度、入度以及度;
(2) 從第一個頂點出發,求一個深度優先遍歷序列;
(3) 從第一個頂點頂點出發,求一個廣度優先遍歷序列。
注意:以使用者輸入各個頂點的順序為頂點的序號。
在深度和廣度優先遍歷中,優先選擇序號小的頂點。
- java程式碼
public class Gragh { AdjMatrix G; private boolean[] visited; public Gragh(){ Scanner sc = new Scanner(System.in); System.out.println("輸入頂點數和邊數:"); int vertexnum = sc.nextInt(); int arcnum = sc.nextInt(); G = new AdjMatrix(vertexnum,arcnum); System.out.println("輸入頂點資訊:"); for(int i = 1;i <= G.vertexnum;i++) { G.vertex[i] = sc.next().charAt(0); } //初始化鄰接矩陣 for(int i = 1;i <= G.vertexnum;i++) { for(int j = 1;j <= G.vertexnum;j++) { G.arcs[i][j] = 0; } } //建立有向圖 System.out.println("輸入頭和尾頂點:"); int head = 0,tail = 0; for(int i = 0;i < G.arcnum;i++) { char vertex_head = sc.next().charAt(0); char vertex_tail = sc.next().charAt(0); for(int j = 1;j <= G.vertexnum;j++) { if(G.vertex[j] == vertex_head) { head = j; for(int k = 1;k <= G.vertexnum;k++) { if(G.vertex[k] == vertex_tail) tail = k; } } } G.arcs[head][tail] = 1; } sc.close(); } /* * 結點的出度、入度、度 */ public void degree() { for(int i = 1;i <= G.vertexnum;i++) { int count_out = 0; int count_in = 0;int count = 0; for(int j = 1;j <= G.vertexnum;j++) { if(G.arcs[j][i] == 1) count_in++; if(G.arcs[i][j] == 1) count_out++; count = count_in + count_out; } System.out.println(G.vertex[i] + " " + count_out + " " + count_in + " " + count); } } private void DFS(int start) { visited = new boolean[G.vertexnum + 1]; Stack<Integer> s = new Stack<>(); s.push(start); System.out.print(G.vertex[start]); visited[start] = true; while(!s.empty()) { int top = s.peek(); boolean is_push = false; for(int i = 1;i <= G.vertexnum;i++) { if(G.arcs[top][i] == 1 && visited[i] == false) { System.out.print(G.vertex[i]); visited[i] = true; s.push(i); is_push = true; break; } } if(is_push == false) { s.pop(); } } } public void DFSTraverse() { visited = new boolean[G.vertexnum + 1]; for(int i = 1;i <= G.vertexnum;i++) { if(visited[i] == false) DFS(i); } } private void BFS(int start) { visited = new boolean[G.vertexnum + 1]; Queue<Integer> q = new LinkedList<>(); System.out.print(G.vertex[start]); visited[start] = true; q.add(start); while(!q.isEmpty()) { int top = q.poll(); for(int i = 1;i <= G.vertexnum;i++) { if(G.arcs[top][i] == 1 && visited[i] == false) { System.out.print(G.vertex[i]); visited[i] = true; q.add(i); } } } } public void BFSTraverse() { visited = new boolean[G.vertexnum + 1]; for(int i = 1;i <= G.vertexnum;i++) { if(visited[i] == false) BFS(i); } } /* * 列印有向圖 */ public void showGragh(){ System.out.print(" "); for (int i = 1; i <= G.vertexnum; i++) {//列印頂點資訊 System.out.print(G.vertex[i] + " "); } System.out.println(); for (int i = 1; i <= G.vertexnum; i++) {//列印鄰接矩陣 System.out.print(G.vertex[i] + " "); for (int j = 1; j <= G.vertexnum; j++) { System.out.print(G.arcs[i][j] + " "); } System.out.println(); } } } class AdjMatrix{ final int MAX_VERTEX = 20; //最大頂點個數 int[][] arcs = new int[MAX_VERTEX][MAX_VERTEX]; //邊資訊 char[] vertex = new char[MAX_VERTEX]; //頂點資訊 int vertexnum; //頂點數 int arcnum; //邊數 AdjMatrix(int vertexnum,int arcnum) { this.vertexnum = vertexnum; this.arcnum = arcnum; } }
- 測試函式
public static void main(String[] args)
{
Gragh gragh = new Gragh();
gragh.showGragh();
gragh.degree();
gragh.DFSTraverse();
System.out.println();
gragh.BFSTraverse();
}
- 執行結果
輸入頂點數和邊數:
5 7
輸入頂點資訊:
A B C D E
輸入頭和尾頂點:
A B
A E
B C
C D
D A
D B
E C
列印矩陣:
A B C D E
A 0 1 0 0 1
B 0 0 1 0 0
C 0 0 0 1 0
D 1 1 0 0 0
E 0 0 1 0 0
各頂點出度、入度、度:
A 2 1 3
B 1 2 3
C 1 2 3
D 2 1 3
E 1 1 2
DFS遍歷:
ABCDE
BFS遍歷:
ABECD