PAT--List Components (25)--BFS,DFS经典

本文深入探讨了广度优先搜索(BFS)与深度优先搜索(DFS)算法,并通过具体实例详细解析了两种算法的工作原理及流程。文章对比了BFS与DFS在遍历过程中的区别,特别关注算法中打印位置的影响,以及如何正确使用visited数组来避免重复访问。

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

http://www.patest.cn/contests/mooc-ds2015spring/06-图1

觉得这题很经典,有利于理解BFS和DFS内部流程。

尤其注意打印位置,括号分出来打印,DFS里面只打印数字。。。

更新:

/*<span style="color:#ff0000;">20150406更新</span>
*后来又研究了一下BFS,哈哈,修改如下
*现在理解比较清楚了,你在visited[]=true处打印,
*肯定只访问一次啦。亲,我之前写的当笑话看啦,
*可以看到我的进步哟
*/
void BFS(int x){
	while(!Q.empty())Q.pop();
	Q.push(x);
	int i;
	visited[x]=true;///
	printf(" %d",x);
	while(!Q.empty()){
		int t=Q.front();
		Q.pop();
		for(i=0;i<n;i++){
			if(!visited[i] && map[i][t]==1){
				//printf("\nt,i:%d,%d",t,i);
				Q.push(i);
				visited[i]=true;
				printf(" %d",i);
			}
		}
	}
}


#include<stdio.h>
#include<queue>
using namespace std;

//地图
int map[10][10];
bool visited[10];
//BFS需要
queue<int> Q;

//初始化visited和Q
void init(){
	int i;
	for(i=0;i<10;i++){
		visited[i]=false;
	}
	while(!Q.empty())Q.pop();
}

//记录节点数
int n;
//深度优先,对应单个连通集
//注意visited[x]和printf的位置
void DFS(int x){
	visited[x]=true;
	printf(" %d",x);
	int i;
	for(i=0;i<n;i++){
		if(map[x][i]==1 && visited[i]==false){
			DFS(i);
		}
	}
}
//将每个连通集输出
void dfscom(){
	int i;
	for(i=0;i<n;i++){
		if(!visited[i]){
			printf("{");
			DFS(i);
			printf(" }\n");
		}
	}
}

//注意两个visited[]位置。
//一开始我只写一个visited,在print后,也就是打印相当于访问
//如下(错误的代码)
/*
void BFS(int x){
	while(!Q.empty())Q.pop();
	Q.push(x);
	int i;
	while(!Q.empty()){
		int t=Q.front();
		Q.pop();
		printf(" %d",t);
		visited[i]=true;//这样在打印前可能入队列很多次。。。。
		//建议可以在打印前判断是否是访问过。只不过会浪费一些队列位置
		for(i=0;i<n;i++){
			if(!visited[i] && map[i][t]==1){
				//printf("\nt,i:%d,%d",t,i);
				Q.push(i);
			}
		}
	}
}
*/

void BFS(int x){
	while(!Q.empty())Q.pop();
	Q.push(x);
	int i;
	visited[x]=true;///
	while(!Q.empty()){
		int t=Q.front();
		Q.pop();
		printf(" %d",t);
		for(i=0;i<n;i++){
			if(!visited[i] && map[i][t]==1){
				//printf("\nt,i:%d,%d",t,i);
				Q.push(i);
				visited[i]=true;
			}
		}
	}
}
void bfscom(){
	int i;
	for(i=0;i<n;i++){
		if(!visited[i]){
			printf("{");
			BFS(i);
			printf(" }\n");
		}
	}
}

	


int main(){
	init();
	int e;
	int i,j;
	for(i=0;i<10;i++){
		for(j=0;j<10;j++){
			map[i][j]=0;
		}
	}

	scanf("%d%d",&n,&e);
	while(e--){
		int t1,t2;
		scanf("%d%d",&t1,&t2);
		map[t1][t2]=1;
		map[t2][t1]=1;
	}
	dfscom();
	//注意初始化
	init();
	bfscom();
	return 0;
}
	


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值