深度优先搜索DFS和广度优先搜索BFS (Java)

无向图
用DFS和BFS对无向图进行遍历搜索,所以先实现无向图,这里用队列实现邻接表,代码如下:

public class Undiagraph {

	private final int vertexNumber; // 顶点数
	private int edgeNuumber; // 边数
	static Queue<Integer>[] adj; // 邻接表,用队列实现(二维)
	
	// 无向图构造器
	@SuppressWarnings("unchecked")
	public Undiagraph(int vertexNumber) {
		this.vertexNumber = vertexNumber;
		this.edgeNuumber = 0;
		
		//初始化邻接表adj
		adj = new Queue[vertexNumber];
		for (int i = 0; i < vertexNumber; i++)
			adj[i] = new LinkedList<Integer>(); // 因为Queue是接口,所以用链表进行初始化
	}
	
	public int getVertexNumber() {
		return vertexNumber;
	}
	
	public int getEdgeNumber() {
		return edgeNuumber;
	}
	
	// 向邻接表中添加边
	public void addEdge(int oldNode, int newNode) {
		// 这里和有向图的添加边的方法有区别
		adj[oldNode].add(newNode); // 将newNode添加到oldNode的链表中
		adj[newNode].add(oldNode); // 将oldNode添加到newNode的链表中
		edgeNuumber++;
	}
	
	// 由node指出的边所连接的所有顶点
	public Iterable<Integer> adj(int node) {
		return adj[node];
	}
}

1、深度优先搜索(DFS)

	/**
	 * 1、深度优先搜索:类似于树的先序遍历
	 * @param graph 图
	 * @param startNode 开始顶点
	 * 
	 * 重要变量:
	 * adj
	 * startNode
	 * visited 全局变量
	 */
	public static void DepthFirstSearch(Undiagraph graph, int startNode) {
		visited = new boolean[graph.getVertexNumber()]; // 初始化标记数组
		dfs(graph, startNode); // 调用递归方法
	}
	/**
	 * 递归方法
	 * @param graph 图
	 * @param startNode 开始结点,会随着递归的进行变化
	 * 
	 * 重要变量:
	 * adj
	 * startNode
	 * visited 全局变量
	 */
	public static void dfs(Undiagraph graph, int startNode) {
		visited[startNode] = true;
		System.out.print(startNode + " ");
		for (int i : graph.adj(startNode)) { // 递归的第一个限制条件
			if (!visited[i]) dfs(graph, i); // 递归的第二个限制条件
		}
	}

输入以下图进行深度优先搜索:
无向图
执行深度优先搜索的递归过程如下图:
递归过程
代码执行结果如下:

输入上述无向图
输出:
0 1 2 3 4 5 

2、广度优先搜索(BFS)

	/**
	 * 2、广度优先搜索
	 * @param graph 图
	 * @param startNode 开始顶点
	 * 
	 * 重要变量:
	 * adj
	 * startNode
	 * visited 全局变量
	 * queue 该队列保存所有已经被标记过但其邻接表还未被检查过的顶点
	 */
	public static void BreadthFirstSearch(Undiagraph graph, int startNode) {
		visited = new boolean[graph.getVertexNumber()]; // 初始化标记数组
		Queue<Integer> queue = new LinkedList<>(); // 初始化队列
		queue.add(startNode); // 将开始结点加入队列
		visited[startNode] = true;
		
		/* 1、取队列中的下一个顶点node并标记它
		 * 2、检查node对应的邻接表,将与node相邻且未被标记的点入队
		 * 3、循环上述1、2步骤直到队列为空
		 */
		while (!queue.isEmpty()) {
			int node = queue.poll();
			System.out.print(node + " ");
			for (int j : graph.adj(node)) {
				if (!visited[j]) {
					queue.add(j);
					visited[j] = true; // 将顶点入队,该顶点已经被标记但其邻接表还未被检查
				}
			}
		}
	}

代码执行结果如下:

输入上述无向图
输出:
0 1 3 2 4 5 

main函数:

	public static void main(String[] args) {
		Undiagraph graph = new Undiagraph(6);

		// 将边添加到邻接表中
		graph.addEdge(0, 1);
		graph.addEdge(0, 3);
		graph.addEdge(1, 0);
		graph.addEdge(1, 2);
		graph.addEdge(1, 3);
		graph.addEdge(1, 4);
		graph.addEdge(2, 1);
		graph.addEdge(2, 3);
		graph.addEdge(2, 4);
		graph.addEdge(2, 5);
		graph.addEdge(3, 0);
		graph.addEdge(3, 1);
		graph.addEdge(3, 2);
		graph.addEdge(3, 4);	
		graph.addEdge(4, 1);
		graph.addEdge(4, 2);
		graph.addEdge(4, 3);
		graph.addEdge(4, 5);
		graph.addEdge(5, 2);
		graph.addEdge(5, 4);
			
		DepthFirstSearch(graph, 0);
		System.out.println();
		BreadthFirstSearch(graph, 0);
	}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
深度优先遍历和广度优先遍历是图的两种常见遍历算法深度优先遍历(DFS)是一种递归算法,它从图中的某个节点开始,首先访问该节点,然后遍历该节点的所有邻接节点,再依次对每个邻接节点进行深度优先遍历。换句话说,DFS会沿着图的一条路径一直往下遍历,直到遇到没有未访问过的邻接节点为止,再返回上一级节点继续遍历其他未访问过的节点。DFS的实现一般使用递归或栈来保存待访问节点。 广度优先遍历(BFS)是一种队列的算法,它从图中的某个节点开始,首先访问该节点,然后遍历该节点的所有邻接节点,并将这些邻接节点加入队列中。接下来从队列中取出一个节点,再依次遍历该节点的邻接节点,并将未访问过的邻接节点加入队列中,如此往复直到队列为空。BFS的实现一般使用队列来保存待访问节点。 在视频中,可以演示通过图的邻接矩阵或邻接表的形式来表示图,并使用Java代码来实现深度优先遍历和广度优先遍历。对于深度优先遍历,可以从图中的某个节点开始递归地遍历它的邻接节点,并使用一个标记数组来记录节点是否已经访问过。对于广度优先遍历,可以使用一个队列来按照广度优先的顺序遍历图中的节点,并同样使用标记数组来记录节点是否已经访问过。 通过这个视频,观众可以了解到深度优先遍历和广度优先遍历的原理和实现方法,并通过代码示例更好地理解其过程。这些算法在图的遍历、路径查找等问题中应用广泛,对于理解和解决相关问题具有重要意义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值