• 广度优先算法


    对于无向连通图,广度优先搜索是从图的某个顶点v0出发,在访问v0之后,依次搜索访问v0的各个未被访问过的邻接点w1,w2,…。然后顺序搜索访问w1的各未被访问过的邻接点,w2的各未被访问过的邻接点…。即从v0开始,由近至远,按层次依次访问与v0有路径相通且路径长度分别为1,2,…的顶点,直至连通图中所有顶点都被访问一次。

    广度优先搜索在搜索访问一层时,需要记住已被访问的顶点,以便在访问下层顶点时,从已被访问的顶点出发搜索访问其邻接点。所以在广度优先搜索中需要设置一个队列Queue,使已被访问的顶点顺序由队尾进入队列。在搜索访问下层顶点时,先从队首取出一个已被访问的上层顶点,再从该顶点出发搜索访问它的各个邻接点。

    用java实现的深度优先算法代码如下:

    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 队列
     * 
     * @author Thief
     *
     * @param <E>
     */
    public class Queue<E> {
    
    	private List<E> queue = new ArrayList<E>();
    
    	/**
    	 * 入队
    	 * 
    	 * @param e
    	 */
    	public void enqueue(E e) {
    		queue.add(e);
    	}
    
    	/**
    	 * 出队
    	 * 
    	 * @param e
    	 *            队首元素
    	 */
    	public E dequeue() {
    		E e = isEmpty() ? null : queue.get(0);
    		if (e != null) {
    			queue.remove(0);
    		}
    		return e;
    	}
    
    	/**
    	 * 判断当前队列是否为空
    	 * 
    	 * @return
    	 */
    	public boolean isEmpty() {
    		return queue.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 BFS(String startVertex) {
    		Queue<String> queue = new Queue<String>();
    		queue.enqueue(startVertex);
    
    		System.out.println("搜索开始。。。");
    		System.out.print(startVertex);
    
    		while (!queue.isEmpty()) {
    			String vertex = queue.dequeue();
    
    			if (edgeMap.containsKey(vertex)) {
    				for (Edge item : edgeMap.get(vertex)) {
    					if (!item.isVisited) {
    						System.out.print("  -->  ");
    						System.out.print(item.getVertexB());
    
    						item.isVisited = true;
    						for (Edge item2 : edgeMap.get(item.getVertexB())) {
    							if (item2.getVertexB().equals(vertex)) {
    								item2.isVisited = true;
    								break;
    							}
    						}
    
    						queue.enqueue(item.getVertexB());
    					}
    				}
    			}
    		}
    		System.out.println();
    		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.BFS("A");
    		} catch (Exception e) {
    			System.out.println(e.getMessage());
    		}
    
    	}
    }
    

    执行结果如下:

  • 相关阅读:
    Spring MVC源码——Root WebApplicationContext
    ThreadPoolExecutor 源码阅读
    Spark RDD
    HashMap 源码阅读
    不定期更新的IDEA功能整理
    Jvm内存区域和GC
    装饰模式和Java IO
    spring websocket集群问题的简单记录
    Kotlin in Action 笔记
    WebSphere部署Spring Boot
  • 原文地址:https://www.cnblogs.com/minisculestep/p/4978105.html
Copyright © 2020-2023  润新知