package com.hisi.test; import java.util.Deque; import java.util.LinkedList; public class Graph { private int vertexNum; // 頂點個數 private LinkedList<Integer> adjacencyTable[]; // 鄰接表 public Graph(int vertexNum) { this.vertexNum = vertexNum; adjacencyTable = new LinkedList[vertexNum]; for (int i = 0; i < vertexNum; ++i) { adjacencyTable[i] = new LinkedList<>(); } } public void addEdge(int from, int to) { // 無向圖一條邊存兩次 adjacencyTable[from].add(to); adjacencyTable[to].add(from); } /** * 創建 * * 1 - 2 - 3 * 丨 丨 丨 * 4 - 5 - 6 */ public void build() { addEdge(1, 2); addEdge(1, 4); addEdge(2, 3); addEdge(2, 5); addEdge(3, 6); addEdge(4, 5); addEdge(5, 6); for (LinkedList<Integer> list: adjacencyTable) { for(Integer i: list) { System.out.print(" " + i); } System.out.println(); } } public void printProcess(Integer[] process, Integer index) { if (index >= 0) { printProcess(process, process[index]); System.out.print(index + " "); } } /** * 深度優先搜索 (借助棧) */ public void dfs(int start, int target) { if (start == target) { return; } //節點是否訪問過了 Boolean[] hasEnHeap = new Boolean[vertexNum]; for (int i = 1; i < vertexNum; i++) { hasEnHeap[i] = false; } //遍歷的輔助隊列 Deque<Integer> heap = new LinkedList<>(); heap.offer(start); hasEnHeap[start] = true; //遍歷的過程(存上一個節點的index) Integer[] process = new Integer[vertexNum]; for(int i=0; i<process.length; i++) { process[i] = -1; } while (!heap.isEmpty()) { //棧頂出棧 Integer top = heap.pollLast(); //top能到達的點入隊 for (Integer topCanReceive : adjacencyTable[top]) { if (topCanReceive == target) { process[topCanReceive] = top; printProcess(process, topCanReceive); return; } if (!hasEnHeap[topCanReceive]) { //節點出棧時,把跟節點連接的所有節點都入棧(已經入過棧的就不入棧了) heap.offerLast(topCanReceive); hasEnHeap[topCanReceive] = true; process[topCanReceive] = top; } } } } public static void main(String[] args) { Graph graph = new Graph(7); // 比實際頂點數+1 graph.build(); graph.dfs(1, 6); } }
2 4
1 3 5
2 6
1 5
2 4 6
3 5
1 4 5 6 //打印路徑