算法是作用于数据结构之上的,深度优先搜索算法和广度优先搜索算法都是基于“图”这种数据结构。

如何理解图(Graph)

图是一种非线性表数据结构,图中的元素叫做顶点(vertex)。顶点可以与任意其它顶点建立连接关系,这种关系叫做连(edge)
graph1.jpg

邻接表存储方法

graph2.jpg
每个顶点对应一条链表,链表中存储的是与这个顶点相连接的期货顶点。

Graph的代码实现

  1. import java.util.LinkedList;
  2. import java.util.Queue;
  3. public class Graph {
  4. private int vertex; // 图的顶点数
  5. private LinkedList<Integer> adj[]; // 邻接表
  6. public Graph(int v){
  7. this.vertex = v;
  8. adj = new LinkedList[v];
  9. for (int i = 0; i < v; i++){
  10. adj[i] = new LinkedList<>();
  11. }
  12. }
  13. // 无向图的边存两次
  14. public void addEdge(int s, int t){
  15. adj[s].add(t);
  16. adj[t].add(s);
  17. }
  18. /**
  19. * 广度优先搜索
  20. * @param s 源点数
  21. * @param t 目标数
  22. */
  23. public void bfs(int s, int t){
  24. if(s == t) return;
  25. // 记录已访问的点,防上重复访问
  26. boolean[] visited = new boolean[vertex];
  27. visited[s] = true;
  28. // 记录搜索路径
  29. int[] pre = new int[vertex];
  30. for (int i = 0; i < pre.length; i++){
  31. pre[i] = -1;
  32. }
  33. //队列用于存储已被访问,但相连的顶点还没有访问的顶点
  34. Queue<Integer> queue = new LinkedList<>();
  35. queue.add(s);
  36. while (queue.size() != 0){
  37. int w = queue.poll();
  38. for (int i =0; i < adj[w].size(); i++){
  39. int q = adj[w].get(i);
  40. if(!visited[q]){
  41. pre[q] = w;
  42. if(q == t){
  43. print(pre, s, t);
  44. return;
  45. }
  46. visited[q] = true;
  47. queue.add(q);
  48. }
  49. }
  50. }
  51. }
  52. public void print(int[] prev, int s, int t){
  53. if (prev[t] != -1 && t !=s){
  54. print(prev, s, prev[t]);
  55. }
  56. System.out.print(t + " ");
  57. }
  58. public static void main(String[] args) {
  59. Graph graph = new Graph(8);
  60. graph.addEdge(0,1);
  61. graph.addEdge(0,3);
  62. graph.addEdge(1,2);
  63. graph.addEdge(1,4);
  64. graph.addEdge(2,5);
  65. graph.addEdge(4,5);
  66. graph.addEdge(4,6);
  67. graph.addEdge(5,7);
  68. graph.addEdge(6,7);
  69. graph.bfs(0,1);
  70. }
  71. }