fw - dfs: stack/recursive ; bfs : stack/recursive- java version - 2013年12月20日18:37:18

本文介绍了一个简单的图数据结构实现,并展示了如何使用该结构进行广度优先搜索(BFS)和两种深度优先搜索(DFS)。通过具体实例说明了这些基本图算法的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package test_kepler;
import java.util.*;

import test_kepler.Treeandgraph.Node;

public class MyGraph {
	
	//In this class we assume we focus on the node in a graph;
	ArrayList<ArrayList<EdgeNode>> G =  new ArrayList<ArrayList<EdgeNode>>();
	
	int nodeNumber;
	public MyGraph(int nodeNm)
	{
		nodeNumber=nodeNm;
		
		for(int i = 0;i<nodeNumber;++i)
		{
			G.add(new ArrayList<EdgeNode>());
		}
	}
	public void set(int fromNode,int inNode,int edgeValue)
	{
		//fromNode--;
		//inNode--;
		//edgeValue--;
		EdgeNode newedgeNode = null;
		if(fromNode<nodeNumber && inNode < nodeNumber)
		{
			newedgeNode = new EdgeNode(fromNode,inNode,edgeValue);
			G.get(fromNode).add(newedgeNode);
		}
		else
		{
			System.out.println("set number is wrong");
		}
	}
	public void MakeGraph()
	{
		set(0,1,5);
		set(1,3,1);
		set(1,2,3);
		set(0,2,2);
		set(2,3,6);
		set(3,4,8);
		set(0,4,15);
		set(2,0,19);
	}
	public ArrayList<EdgeNode> getNeighbor(int i)
	{
		if(i<nodeNumber)
		{
			return G.get(i);
		}
		else
		{
			System.out.println("query wrong");
			return null;
		}
	}
	public void BFS(int startNode)
	{
		 qbytwostc testq = new qbytwostc<EdgeNode>();
		 
		 //start from 1;
		 //EdgeNode dnd = G.get(0).get(0);//perfect point ~~~
		 System.out.println("this is from "+ startNode);
		 if(G.get(startNode).size() == 0)
		 {
			 System.out.println(startNode+"  is a bad point ");
			 return ;
		 }
		 EdgeNode dnd = G.get(startNode).get(0);
		// dnd.print();
		 testq.enQueue(dnd);
		// System.out.println("after enqueue");
		 while(!testq.isEmpty())
		 {
			 EdgeNode headfrmQueue = (EdgeNode) testq.dequeue();
			 if(headfrmQueue.isVisted == false)
			 {
				 headfrmQueue.isVisted = true;
				 headfrmQueue.print();
			 }
			 
			 Iterator<EdgeNode> it = G.get(headfrmQueue.inNode).iterator();
			 while(it.hasNext())
			 {
				 EdgeNode x = it.next();
				 if(x.isVisted == false)
				 {
					 x.isDiscovered = true;
					 testq.enQueue(x);
				 }
			 }
			 
			 Iterator<EdgeNode> it2 = G.get(headfrmQueue.fromNode).iterator();
			 while(it2.hasNext())
			 {
				// System.out.println("2??");
				 EdgeNode x2 = it2.next();
				if(x2.isVisted == false)// && x2.isDiscovered == false)
				 {
					 x2.isDiscovered = true;
					 testq.enQueue(x2);
				 }
			 }
		 }	 
		 clear();
	}
	// dfs - recursive
	public void DFS(EdgeNode startNode)
	{
		if(startNode.isVisted == false)
		{
			startNode.print();
			startNode.isVisted = true;
		}
		
		
		 Iterator<EdgeNode> it = G.get(startNode.inNode).iterator();
		 while(it.hasNext())
		 {
			 EdgeNode x = it.next();
			 if(x.isVisted == false)
			 {
				DFS(x);
			 }
		 }
		 
		 Iterator<EdgeNode> it2 = G.get(startNode.fromNode).iterator();
		 while(it2.hasNext())
		 {
			// System.out.println("2??");
			 EdgeNode x2 = it2.next();
			if(x2.isVisted == false)// && x2.isDiscovered == false)
			 {
				this.DFS(x2);
			 }
		 }
		
	}
	// wrap for DFS
	public void DFS_wrap(int startNode)
	{
		 if(G.get(startNode).size() == 0)
		 {
			 System.out.println(startNode+"  is a bad point ");
			 return ;
		 }
		 EdgeNode BGNd = G.get(startNode).get(0);
			// dnd.print();
		 System.out.println("this is from" + startNode+"====");
		// DFS(BGNd);
		 DFS_Estack(BGNd);
		 this.clear();
	}
	
	public void print()
	{
		for(int index = 0;index<nodeNumber;++index)
		{
			Iterator<EdgeNode> it = G.get(index).iterator();
			while(it.hasNext())
			{
				EdgeNode x = it.next();
				x.print();
			}
			
			System.out.println("in the next line");
		}
	}
	// CLEAR ALL THE node as un-visited
	void clear()
	{
		for(int index = 0;index<nodeNumber;++index)
		{
			Iterator<EdgeNode> it = G.get(index).iterator();
			while(it.hasNext())
			{
				EdgeNode x = it.next();
				x.isVisted = false;
				x.isDiscovered = false;
			}
			
			//System.out.println("in the next line");
		}
	}
	// bfs seems easy so ; we will use dfs;
	boolean isconnected(EdgeNode e1,EdgeNode e2)// the first node connected to the node 1 and node 2;
	{
		return false;
	}
	// test whether from the s->e->s;
	public boolean  iscyccnct(int startNd,int endNd)
	{
		return false;
	}
	// dfs with explicit stack
	// the call the function itself is a kind of push stack; 
	// it can even get back ~~~ because the stack will pop to the ; changing-to-another-place across corneer ``
	public void DFS_Estack(EdgeNode startNd1)
	{
		Stack<EdgeNode> dfs_stack = new Stack<EdgeNode>();
		dfs_stack.push(startNd1);
		while(!dfs_stack.isEmpty())
		{
			EdgeNode startNd = dfs_stack.pop();
			
			if(startNd.isVisted == false)
			{
				startNd.print();
				startNd.isVisted = true;
			}
			
			Iterator<EdgeNode> it = G.get(startNd.fromNode).iterator();
			while(it.hasNext())
			{
				EdgeNode newNode = it.next();
				if(newNode.isVisted == false)
				dfs_stack.push(newNode);
			}
			
			Iterator<EdgeNode> it2 = G.get(startNd.inNode).iterator();
			while(it2.hasNext())
			{
				EdgeNode newNode = it2.next();
				if(newNode.isVisted == false)
				dfs_stack.push(newNode);
			}
		}
		
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyGraph mg= new MyGraph(5);
		mg.MakeGraph();
		mg.print();
		System.out.println("==== BFS RESULT ==== ");
		//mg.BFS(4);
		
		for(int i = 0;i<5;++i)
		{
			mg.DFS_wrap(i);
		}
	}

}

<think>好的,我现在需要回答用户关于DFSBFS算法区别与实现的问题。首先,我得回忆这两个算法的基本概念,确保自己理解正确。DFS是深度优先搜索,也就是尽可能深地遍历树的节点,直到到达叶子节点再回溯。而BFS是广度优先搜索,逐层扩展,先访问离起点近的节点。这是它们的核心区别。 接下来,我需要明确它们的区别,可能包括遍历顺序、数据结构、空间复杂度等方面。比如,DFS通常用栈或递归实现,而BFS用队列。空间复杂度方面,BFS在最坏情况下可能比DFS高,尤其是当树比较宽的时候。 然后,实现部分,用户可能需要代码示例。DFS可以用递归或者显式的栈来实现,而BFS一般用队列。我需要写出这两种算法的Python代码,确保语法正确,并且加上注释说明。 还要注意用户提到的系统级指令,比如数学表达式要用$...$格式,独立公式用$$...$$,不过这个问题可能数学公式不多,但如果有涉及树或图的节点数、层数等,可能需要用到。例如,树的高度h,BFS的时间复杂度是$O(n)$,而DFS可能是$O(h)$,但得根据具体情况判断。 另外,用户要求生成相关问题,我需要想几个相关的问题,比如比较它们的优缺点,应用场景,或者如何选择两者等。这些问题应该能帮助用户进一步学习。 现在,检查是否有引用需要添加。用户提供的引用[1]和[2]提到了DFSBFS的原理和结构,所以在回答中可以引用这些内容,特别是在提到它们的遍历方式时,比如引用[^2]说明它们搜索的结构像树,DFS深入,BFS逐层扩展。 最后,确保回答结构清晰,分点说明区别,代码部分用正确的格式,语言用中文,没有使用任何markdown,符合用户的要求。可能需要多次检查LaTeX语法是否正确,比如变量是否用$包围,是否有拼写错误等。 总结步骤: 1. 介绍DFSBFS的基本概念,引用提供的资料。 2. 分点列出它们的区别,包括遍历顺序、数据结构、空间复杂度、应用场景等。 3. 提供实现代码,Python的递归DFS、栈实现的DFS,队列实现的BFS。 4. 生成相关问题,如优缺点比较、应用例子、如何选择等。 5. 确保所有引用正确添加,比如在提到遍历结构时引用。</think>### DFSBFS 算法的区别与实现 #### 一、基本概念 1. **DFS(深度优先搜索)**:从起点出发,尽可能深地遍历分支,直到无法继续再回溯到上一个节点,尝试其他分支。搜索结构像一棵树,优先探索“深度”。 2. **BFS(广度优先搜索)**:从起点出发,逐层扩展,先访问离起点最近的节点。搜索时按“层级”逐步推进。 #### 二、核心区别 | 特性 | DFS | BFS | |--------------|------------------------------|------------------------------| | **遍历顺序** | 深度优先(纵向) | 广度优先(横向) | | **数据结构** | 栈(递归或显式栈) | 队列 | | **空间复杂度** | $O(h)$(h为树的高度) | $O(w)$(w为树的最大宽度) | | **应用场景** | 解决连通性、路径存在性问题 | 最短路径、层级遍历 | #### 三、实现代码 ##### 1. DFS 实现(递归) ```python def dfs_recursive(graph, node, visited): if node not in visited: print(node) # 处理当前节点 visited.add(node) for neighbor in graph[node]: dfs_recursive(graph, neighbor, visited) # 示例图的邻接表 graph = { 'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F'], 'D': [], 'E': ['F'], 'F': [] } visited = set() dfs_recursive(graph, 'A', visited) # 从节点A开始 ``` ##### 2. DFS 实现(显式栈) ```python def dfs_stack(graph, start): stack = [start] visited = set() while stack: node = stack.pop() if node not in visited: print(node) # 处理当前节点 visited.add(node) # 按逆序压栈以保证与递归顺序一致 for neighbor in reversed(graph[node]): stack.append(neighbor) ``` ##### 3. BFS 实现(队列) ```python from collections import deque def bfs_queue(graph, start): queue = deque([start]) visited = set() while queue: node = queue.popleft() if node not in visited: print(node) # 处理当前节点 visited.add(node) for neighbor in graph[node]: queue.append(neighbor) ``` #### 四、应用场景对比 - **DFS适用场景**: - 拓扑排序(如任务依赖解析) - 检测图中的环 - 解决迷宫问题(只需判断是否存在路径) - **BFS适用场景**: - 社交网络中的“最短关系链” - 无权图的最短路径(如迷宫最短路径) - 网页爬虫按层级抓取 #### 五、性能分析 - **DFS空间优势**:递归深度与树高相关,适合纵深大的结构。 - **BFS时间优势**:若解靠近起点,BFS能更快找到最短路径,但可能占用更多内存[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值