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 //打印路径