深度优先算法所遵循的搜索策略是尽可能“深”地搜索一个图。在深度优先搜索中,对于最新发现的定点,如果它还有以此为起点而未探测到的边,就沿此边继续探测下去。当顶点v的所有边都已被探寻过后,搜索将回溯到发现顶点v的点。这一过程一直进行到发现从源顶点可达的所有顶点位置为止。
用java实现的深度优先算法代码如下:
import java.util.List; import java.util.ArrayList; /** * 栈 */ public class Stack<E> { private List<E> stack = new ArrayList<E>(); /** * 进栈 * * @param 进栈元素 */ public void push(E e) { stack.add(e); } /** * 出栈 * * @return 栈顶元素 */ public E pop() { if (!isEmpty()) { E result = stack.get(stack.size() - 1); stack.remove(stack.size() - 1); return result; } else { return null; } } /** * 取栈顶元素 * * @return 栈顶元素 */ public E top() { if (!isEmpty()) { return stack.get(stack.size() - 1); } else { return null; } } /** * 查询栈是否为空 * * @return */ public boolean isEmpty() { return stack.isEmpty(); } }
/** * 边 * * @author Thief * */ public class Edge { public Edge(String vertexA, String vertexB) { super(); this.vertexA = vertexA; this.vertexB = vertexB; } /** * 顶点A */ private String vertexA; /** * 顶点B */ private String vertexB; /** * 该边是否已经被访问 */ boolean isVisited = false; public String getVertexA() { return vertexA; } public void setVertexA(String vertexA) { this.vertexA = vertexA; } public String getVertexB() { return vertexB; } public void setVertexB(String vertexB) { this.vertexB = vertexB; } public boolean isVisited() { return isVisited; } public void setVisited(boolean isVisited) { this.isVisited = isVisited; } }
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 图 * * @author Thief * */ public class Graph { /** * 顶点 */ private List<String> vertexList = new ArrayList<String>(); /** * 边 */ private Map<String, List<Edge>> edgeMap = new HashMap<String, List<Edge>>(); /** * 向图中添加顶点 * * @param vertex * 顶点名字 * @throws Exception * 当顶点已经存在时抛出异常 */ public void addVertex(String vertex) throws Exception { if (vertexList.contains(vertex)) { throw new Exception("该顶点已经存在!"); } else { vertexList.add(vertex); } } /** * 向图中添加边 * * @param vertexName_A * 顶点A的名字 * @param vertexName_B * 顶点B的名字 * @throws Exception * 顶点不存在或边已经存在时抛出异常 */ public void addEdge(String vertexA, String vertexB) throws Exception { if (!vertexList.contains(vertexA) || !vertexList.contains(vertexB)) { throw new Exception("顶点不存在!"); } if (containsEdge(vertexA, vertexB)) { throw new Exception("边已经存在"); } if (edgeMap.containsKey(vertexA)) { List<Edge> list = edgeMap.get(vertexA); list.add(new Edge(vertexA, vertexB)); } else { List<Edge> list = new ArrayList<Edge>(); list.add(new Edge(vertexA, vertexB)); edgeMap.put(vertexA, list); } if (edgeMap.containsKey(vertexB)) { List<Edge> list = edgeMap.get(vertexB); list.add(new Edge(vertexB, vertexA)); } else { List<Edge> list = new ArrayList<Edge>(); list.add(new Edge(vertexB, vertexA)); edgeMap.put(vertexB, list); } } /** * 判断图中该边是否已经存在 * * @param vertexA * 顶点A * @param vertexB * 顶点B * @return 如果存在返回true,否则返回false */ private boolean containsEdge(String vertexA, String vertexB) { boolean isExist = false; if (edgeMap.containsKey(vertexA)) { List<Edge> list = edgeMap.get(vertexA); if (list.contains(new Edge(vertexA, vertexB))) { isExist = true; } } return isExist; } /** * 深度优先搜索 * * @param startVertex * 起点 */ public void DFS(String startVertex) { Stack<String> stack = new Stack<String>(); stack.push(startVertex); System.out.println("搜索开始。。。"); while (!stack.isEmpty()) { String currentVertex = stack.top(); //判断与该顶点相连的边是否都已经被访问 boolean isAllVisited = true; for (Edge edge : edgeMap.get(currentVertex)) { if (!edge.isVisited) { isAllVisited = false; break; } } if (isAllVisited) { stack.pop(); if (!stack.isEmpty()) { System.out.println(currentVertex + " --> " + stack.top()); } } else { List<Edge> listA = edgeMap.get(currentVertex); for (Edge edge : listA) { if (!edge.isVisited) { stack.push(edge.getVertexB()); System.out.println(currentVertex + " --> " + edge.getVertexB()); edge.isVisited = true; // 将边BA的访问标志置为true List<Edge> listB = edgeMap.get(edge.getVertexB()); for (Edge item : listB) { if (item.getVertexB().equals(currentVertex)) { item.isVisited = true; } } break; } } } } System.out.println("搜索结束。。。"); } }
测试代码如下:
public class Test { public static void main(String[] args) { Graph graph = new Graph(); try { graph.addVertex("A"); graph.addVertex("B"); graph.addVertex("C"); graph.addVertex("D"); graph.addVertex("E"); graph.addVertex("F"); graph.addVertex("G"); graph.addEdge("A", "B"); graph.addEdge("B", "C"); graph.addEdge("B", "D"); graph.addEdge("A", "E"); graph.addEdge("E", "F"); graph.addEdge("A", "G"); graph.DFS("A"); } catch (Exception e) { System.out.println(e.getMessage()); } } }
执行结果如下:
搜索开始。。。
A --> B
B --> C
C --> B
B --> D
D --> B
B --> A
A --> E
E --> F
F --> E
E --> A
A --> G
G --> A
搜索结束。。。