数据结构与算法-深度优先搜索

Posted 算法半岛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构与算法-深度优先搜索相关的知识,希望对你有一定的参考价值。

点击上面"算法半岛"

关注"算法半岛"第一时间接收最新文章


DFS理解

    深度优先搜索(Depth First Search, DFS)可以理解为走迷宫,假设当一个人走迷宫的时候,会遇到岔路口,面对多条路选择时,可以先随便选择一条,走着走着发现如果走不通了,可以退回到上一个岔路口,然后重新选择一条,用同样的方法继续走,直到直到出口为止。这样的策略即为DFS。

DFS示意图

    接下来我们将DFS应用到图的搜索中,如下图所示:

DFS代码

    在完成相应的 java代码前,我们先解释相关函数及参数的含义:

  • HashMap<Integer,LinkedList<Integer>>graph:我们使用一个 HashMap来存储图,其中 HashMap中的 key为图的顶点, LinkedList<Integer>>为与该顶点相连的顶点;

  • HashMap<Integer,Boolean>visited:我们使用一个 visited用来记录顶点是否被访问,用来避免顶点被重复访问;

  • visit(HashMap<Integer,LinkedList<Integer>>graph,HashMap<Integer,Boolean>visited,Integerstart):该函数为DFS的主体部分,用来遍历各个顶点。

    具体 java代码如下所示:

 
   
   
 
  1. import java.util.HashMap;

  2. import java.util.LinkedList;


  3. public class TestDFS {


  4. private static void dfs(HashMap<Integer, LinkedList<Integer>> graph, HashMap<Integer, Boolean> visited){

  5. visit(graph, visited, 1);

  6. visit(graph, visited, 2);

  7. }



  8. private static void visit(HashMap<Integer, LinkedList<Integer>> graph, HashMap<Integer, Boolean> visited, Integer start){

  9. // 如果该顶点没有被访问,则访问该顶点

  10. if (!visited.containsKey(start)){

  11. System.out.println("当前进入节点为:" + start);

  12. visited.put(start, true);

  13. // 访问该顶点的相连顶点

  14. for (Integer i : graph.get(start)){

  15. if (!visited.containsKey(i)){

  16. visit(graph,visited, i); // 递归访问相连顶点

  17. }

  18. }

  19. System.out.println("当前离开节点为:" + start);

  20. }

  21. }


  22. public static void main(String[] args) {


  23. // 构造各个顶点

  24. LinkedList<Integer> v1 = new LinkedList<>();

  25. v1.add(2);

  26. v1.add(3);

  27. v1.add(4);

  28. LinkedList<Integer> v2 = new LinkedList<>();

  29. v2.add(1);

  30. v2.add(3);

  31. LinkedList<Integer> v3 = new LinkedList<>();

  32. v3.add(1);

  33. v3.add(2);

  34. LinkedList<Integer> v4 = new LinkedList<>();

  35. v4.add(1);

  36. v4.add(5);

  37. v4.add(6);

  38. LinkedList<Integer> v5 = new LinkedList<>();

  39. v5.add(4);

  40. LinkedList<Integer> v6 = new LinkedList<>();

  41. v6.add(4);

  42. v6.add(7);

  43. LinkedList<Integer> v7 = new LinkedList<>();

  44. v7.add(6);


  45. // 构造图

  46. HashMap<Integer, LinkedList<Integer>> graph = new HashMap<>();

  47. graph.put(1, v1);

  48. graph.put(2, v2);

  49. graph.put(3, v3);

  50. graph.put(4, v4);

  51. graph.put(5, v5);

  52. graph.put(6, v6);

  53. graph.put(7, v7);


  54. // visited数组记录被访问的节点

  55. HashMap<Integer, Boolean> visited = new HashMap<>();


  56. dfs(graph, visited);


  57. }

  58. }

    输出结果:

 
   
   
 
  1. 当前进入节点为:1

  2. 当前进入节点为:2

  3. 当前进入节点为:3

  4. 当前离开节点为:3

  5. 当前离开节点为:2

  6. 当前进入节点为:4

  7. 当前进入节点为:5

  8. 当前离开节点为:5

  9. 当前进入节点为:6

  10. 当前进入节点为:7

  11. 当前离开节点为:7

  12. 当前离开节点为:6

  13. 当前离开节点为:4

  14. 当前离开节点为:1