【算法】图的深度优先搜索(DFS)

avatar
作者
猴君
阅读量:0
深度优先搜索的基本思想

1.深度优先搜索,从初始访问节点出发,初始访问节点可能有多个邻接节点,深度优先搜索的策略就是首先访问第一个邻接节点,然后再以这个被访问的邻接节点为初始节点,访问它的第一个邻接节点。可以这样理解:每次都在访问完当前节点后首先访问当前节点的第一个邻接节点

2.我们可以看到,这样的访问策略是优先往纵向挖掘深入,而不是对一个节点的所有邻接节点进行横向访问

3.显然,深度优先搜索是一个递归的过程

深度优先按搜索算法步骤

1.访问初始节点 v,并标记节点 v 为已访问

2.查找节点 v 的第一个邻接节点 w

3.若 w 存在,则继续执行 4,如果 w 不存在,则回到第 1 步,将从 v 的下一个节点继续

4.若 w 未被访问,对 w 进行深度优先遍历递归(即把 w 当作另一个 v,然后进行步骤 1 2 3)

5.查找节点 v 的 w 邻接节点的下一个邻接节点,转到步骤 3


public class Graph {     private ArrayList<String> vertexList;  //存储顶点的集合     private int[][] edges;  //存储图对应的邻接矩阵     private int numOfEdges;  //表示边的数目     //定义一个数组 boolean[],记录某个节点是否被访问     private boolean[] isVisited;      public static void main(String[] args) {         //测试         int n = 5;  //节点的个数         String[] Vertexs = {"A", "B", "C", "D", "E"};         //创建图对象         Graph graph = new Graph(n);         //循环的添加顶点         for (String vertex : Vertexs) {             graph.insertVertex(vertex);         }          //添加边         // A-B  A-C  B-C  B-D  B-E         graph.insertEdge(0, 1, 1);         graph.insertEdge(0, 2, 1);         graph.insertEdge(1, 2, 1);         graph.insertEdge(1, 3, 1);         graph.insertEdge(1, 4, 1);          graph.showGraph();          //测试 dfs         System.out.println("深度遍历");         graph.dfs();     }      //构造器     public Graph(int n) {         //初始化矩阵和 vertexList         edges = new int[n][n];         vertexList = new ArrayList<String>(n);         numOfEdges = 0;         isVisited = new boolean[n];     }      //得到第一个邻接节点的下标 w     /**      *      * @param index      * @return  如果存在,返回对应下标,否则返回 -1      */     public int getFirstNeighbor(int index) {         for (int j = 0;j < vertexList.size(); j++) {             if (edges[index][j] > 0) {                 return j;             }         }         return -1;     }      //根据前一个邻接节点的下标来获取下一个邻接节点     public int getNextNeighbor(int v1, int v2) {         for (int j = v2 + 1; j < vertexList.size(); j++) {             if (edges[v1][j] > 0) {                 return j;             }         }         return -1;     }      //深度优先搜索算法     private void dfs(boolean[] isVisited, int i) {         //首先我们访问该节点,输出         System.out.print(getValueByIndex(i) + " -> ");         //将节点设置为已经访问         isVisited[i] = true;         //查找节点 i 的第一个邻接节点 w         int w = getFirstNeighbor(i);         while (w != -1) {  //说明存在             if (!isVisited[w]) {                 dfs(isVisited, w);             }             //如果 w 节点已经被访问过             w = getNextNeighbor(i, w);         }     }      //对 dfs 进行一个重载,遍历我们所有的节点,并进行 dfs     public void dfs() {         //遍历所有的节点,进行 dfs (回溯)         for (int i = 0; i < getNumOfEdges(); i++) {             if (!isVisited[i]) {                 dfs(isVisited, i);             }         }     }      //图中常用的方法     //返回节点的个数     public int getNumOfVertex() {         return vertexList.size();     }     //返回边的个数     public int getNumOfEdges() {         return numOfEdges;     }     //返回节点 i(下标)对应的数据 0->"A" 1->"B" 2->"C"     public String getValueByIndex(int i) {         return vertexList.get(i);     }     //返回 v1 和 v2 的权值     public int getWeight(int v1, int v2) {         return edges[v1][v2];     }     //显示图对应的矩阵     public void showGraph() {         for (int[] link : edges) {             System.out.println(Arrays.toString(link));         }     }      //插入节点     public void insertVertex(String vertex) {         vertexList.add(vertex);     }      //添加边     /**      *      * @param v1  代表第一个顶点对应的下标      * @param v2  代表第二个顶点对应的下标      * @param weight      */     public void insertEdge(int v1, int v2, int weight) {         edges[v1][v2] = weight;         edges[v2][v1] = weight;         numOfEdges++;     } }

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!