深度优先(DFS)

来源:互联网 发布:淘宝大件退货 编辑:程序博客网 时间:2024/04/29 21:33

算法的伪代码描述为:

DFS(G)

for each vertex uV [G]

2       do color[u] ← WHITE

3          π[u] ← NIL

time ← 0

for each vertex uV [G]

6       do if color[u] = WHITE

7             then DFS-VISIT(u)

DFS-VISIT(u)

color[u] ← GRAY     ▹White vertex u has just been discovered.

timetime +1

d[u] time

for each vAdj[u]  ▹Explore edge(u,v).

5       do if color[v] = WHITE

6             then π[v] ← u

7                 DFS-VISIT(v)

color[u] ←BLACK      ▹ Blacken u; it is finished.

f [u] ←timetime +1

在程序中,d[u]表示为first[u],f[u]表示为last[u]

下面代码中使用邻接表(adjacency list)来表示,结构如下图所示:

根据上述算法描述深度优先的过程图示如下:

其中顶点上面的标志为 first(v)/last(v)即第一次访问该结点的时间和最后一次访问该结点的时间

 

算法实现代码如下:

 

package _20120204;import java.util.ArrayList;public class DFS {public String[] color;public int[] parent;public int[] first;public int[] last;public int time = 0;public ArrayList<ArrayList<Integer>> graph = new ArrayList<ArrayList<Integer>>();public ArrayList<ArrayList<Integer>> graph(){int[] sub1 = {1,2,5};int[] sub2 = {2,1,5,3,4};int[] sub3 = {3,2,4};int[] sub4 = {4,2,5,3};int[] sub5 = {5,4,1,2};graph.add(creatList(sub1));graph.add(creatList(sub2));graph.add(creatList(sub3));graph.add(creatList(sub4));graph.add(creatList(sub5));return graph;}/** * make an array to a list... * @param source * @return */public ArrayList<Integer> creatList(int[] source){ArrayList<Integer> subList = new ArrayList<Integer>();for(int i = 0;i < source.length;i++){subList.add(source[i]);}return subList;}public DFS(){this.graph();color = new String[graph.size()];first = new int[graph.size()];last = new int[graph.size()];parent = new int[graph.size()];for(int i = 0;i < graph.size();i++){color[i] = "white";parent[i] = -1;}for(int i = 0;i < graph.size();i++){if(color[i].equals("white")){DFS_VISIT(i);}}for(int i = 0;i < graph.size();i++){System.out.println("节点 "+(i+1)+" 的父节点为 "+this.parent[i]);}}public void DFS_VISIT(int node){        System.out.println("当前访问的节点是: "+(node+1));color[node] = "gray";this.time = this.time+1;first[node] = this.time;        System.out.println("第一次访问节点 "+(node+1)+" 的顺序为: "+first[node]);for(int i = 1;i < graph.get(node).size();i++){if(color[graph.get(node).get(i)-1].equals("white")){parent[graph.get(node).get(i)-1] = node+1;DFS_VISIT(graph.get(node).get(i)-1);}}color[node] = "black";this.time = this.time+1;last[node] = this.time;        System.out.println("最后一次访问节点 "+(node+1)+" 的顺序为: "+last[node]);}public static void main(String[] args){DFS dfs = new DFS();}}

程序运行结果如下:

当前访问的节点是: 1

第一次访问节点 1 的顺序为: 1

当前访问的节点是: 2

第一次访问节点 2 的顺序为: 2

当前访问的节点是: 5

第一次访问节点 5 的顺序为: 3

当前访问的节点是: 4

第一次访问节点 4 的顺序为: 4

当前访问的节点是: 3

第一次访问节点 3 的顺序为: 5

最后一次访问节点 3 的顺序为: 6

最后一次访问节点 4 的顺序为: 7

最后一次访问节点 5 的顺序为: 8

最后一次访问节点 2 的顺序为: 9

最后一次访问节点 1 的顺序为: 10

节点 1 的父节点为 -1

节点 2 的父节点为 1

节点 3 的父节点为 4

节点 4 的父节点为 5

节点 5 的父节点为 2

根据结果得到顶点的访问次序如下图所示: