图的深度优先遍历(递归与非递归算法)和广度优先遍历

2023-10-27

老师的题目::

实验内容

已知某地区的公路网以图表示,图中的顶点表示站点,任意两站点间的路段以带权的边构成的邻接矩阵表示,矩阵中非零元表示两个站点间存在直接的路段,否则没有路段。

打开E:\Test文件夹中的exp06.cpp文件,补充编写所需代码。程序首先进行图的连通性判定,若图连通则输出连通信息,否则继续计算和输出图的连通分量数。

输入数据在文件exp06.in中,首行的整数是站点的总数n(1<n<=30);第2行开始的n行中,每行n个整数,是这n个站点构成的公路网的邻接矩阵。例如,

6

01 3 4 9 0

10 9 9 0 0

39 0 0 6 8

49 0 0 5 7

90 6 5 0 4

00 8 7 4 0

主函数中,在调用读入数据函数readData()时,会自动将矩阵中的零元(除对角线保持0以外)替换成无穷大(9999)。

Search(intv)函数实现从顶点v出发的一次搜索过程,并累计访问顶点数。

若图是连通的,则输出文件exp06.out中包含如下文字:

All vertexsare connected.

否则,计算和输出连通分量数,输出文件的内容则如下例:

    The number of connected components is 2.

解题思路

利用一次深度优先或者广度优先搜索过程中对访问顶点数的计数,并判断其与图的顶点总数是否相等来判定图的连通性。

如果图不连通,则继续从下一个未被访问的顶点出发再进行一次搜索,如此反复,直到已遍历图的所有顶点,累计的搜索次数即是图的连通分量数。

我在代码中都做了注解


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

const int Size=30;
const double INF=9999;		// infinity (无穷大)
int vexnum;					// total number of vertex (顶点总数) 
int adjmat[Size][Size];		// adjacent matrix (邻接矩阵)
int mark[Size];				// vector of visiting mark of vertex (顶点访问标记向量)
int visitnum;				// number of visited vertex for one search (一次搜索中被访问顶点数)
int adjnum;					// number of connected components (连通分量数) 

void readData()
{	int i,j;
	cin>>vexnum;			// input vexnum 
	for(i=0; i<vexnum; i++)
		for(j=0; j<vexnum; j++)
		{	cin>>adjmat[i][j];
			if(i!=j && adjmat[i][j]==0) adjmat[i][j]=INF;
		}
}
/*int first_adj(int v){
	int w;
	for(w=0;w<vexnum;w++)
		if(adjmat[v][w]!=INF||v!=w) return w;
	return -1;	
}
int next_adj(int v,int w){
	for(w+=1;w<vexnum;w++)
		if(adjmat[v][w]!=INF||v!=w) return w;
	return -1;	
}*/
void Search(int v)			// one time search, v represents the starting vertex
{//************************************************
	//********************************************
	/*int w=-1;   //书上的解法,太麻烦了
	mark[v]=1;
	visitnum++;
	w=first_adj(v);
	while(w!=-1){
		if(!mark[w])
			Search(w);
		w=next_adj(v,w);
	}*/
	//==============================================
	

	//**************************************************
	/*递归的深度优先搜索
	int i;
	if(mark[v]==1) return;   //访问过了,要有,可用于判断连通分量
	mark[v]=1;   //否则访问他
	visitnum++;
	for(i=0;i<vexnum;i++){
		if(adjmat[v][i]!=INF&&v!=i&&mark[i]!=1)   //找到未访问过的邻接点
			Search(i);
	}
	return;*/
	//====================================================





	//***************************************************
	/*
	//非递归的深度优先搜索
	int *stack=new int[vexnum],top=-1,w;
	if(mark[v]==1) return;
	stack[++top]=v;
	mark[v]=1;
	visitnum++;
	while(top!=-1){
		v=stack[top];         //不能top--,因为后面还要用到此处节点
		for(w=0;w<vexnum;w++){//找一个未访问的邻接点,可以使用上面的first_adj(v)
			if(adjmat[v][w]!=INF && v!=w && mark[w]!=1)
				break;
		}
		if(w==vexnum) top--;  //此节点   没有   还没找过的邻接点了,退栈
		else{					//有未访问邻接点,人栈,接下来从这个节点继续深度访问
			stack[++top]=w;	
			mark[w]=1;
			visitnum++;
		}
	}
	*/
	//=====================================================


	//*******************************************
	/*
	//广度优先搜索   先访问再入队
	int *queue=new int[vexnum+1],front=0,rear=0;
	int w;
	if(mark[v]==1) return;   
	mark[v]=1;	
	visitnum++;
	queue[rear++]=v;
	while(front!=rear){
		v=queue[front++];
		for(w=0;w<vexnum;w++){   //找到所有未访问邻接点入队
			if(adjmat[v][w]!=INF&&v!=w&&mark[w]!=1){
				queue[rear++]=w;
				mark[w]=1;
				visitnum++;
			}
		}
		//找完了
	}
	//========================================
	*/
 //================================================
}

int main()
{	int i;
/*	freopen("exp06.in", "r", stdin);
	freopen("exp06.out", "w", stdout);*/
	readData();							// input data 
	for(i=0; i<vexnum; i++) mark[i]=0;	// initialze the visiting mark
	visitnum=0;
	Search(0);							// one time search from vertex 0 
	if(visitnum==vexnum) cout<<"All vertexs are connected.\n";
	else 
	{	adjnum=1;
		//************************************************
	for(i=0;i<vexnum;i++){
		if(!mark[i]){
			Search(i);
			adjnum++;
		}
	}
 		//================================================
		cout<<"The number of connected components is "<<adjnum<<".\n";
	}
	return 0;
}



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

图的深度优先遍历(递归与非递归算法)和广度优先遍历 的相关文章

  • 修改mysql的字符集和默认存储引擎

    author skate time 2012 05 18 修改mysql的字符集和默认存储引擎 1 修改mysql的字符集 mysql库现有字符集 mysql gt show variables like character Variabl
  • 多表的 inner join与left join;

    当前情况 目前有三个表 关系如下 1 sc表 有 student id class id 2 student表 有student id student name 3 class表 有class id class name class add
  • vue3+vite+ts项目配置开发环境和生产环境 打包命令配置

    开发环境和生产环境的配置和打包方式有所不同 下面是基于vue3 vite ts项目的开发环境和生产环境配置及打包方式的详细说明 开发环境配置 开发环境的配置主要是为了方便开发者进行调试和测试 以下是开发环境的配置步骤 1 1 安装依赖 首先

随机推荐

  • 51单片机“独立按键”控制静态数码管———显示数字0-9

    51单片机 独立按键 控制静态数码管学习总结 一 按键功能实现总结 独立按键 电路图解析及接线 二 程序编译与控制静态数码管显示1 2 0 9 的效果展示 三 按键程序逻辑设计与程序编译 四 程序烧录与保存 一 按键功能实现总结 独立按键
  • python 绘制两组数据的分布图

    可以使用 Python 中的 Matplotlib 库来绘制两组数据的分布图 下面是一个简单的示例代码 import matplotlib pyplot as plt 假设有两组数据 分别是 x 和 y x 1 2 3 4 5 y 2 4
  • JAVA用线程池模拟查询大批量数据

    JAVA用线程池模拟查询大批量数据 文章目录 JAVA用线程池模拟查询大批量数据 1 前言背景 1 1 线程 1 2 进程与线程的区别总结 1 3 使用多线程的好处 2 多线程的实现 2 1 操作流程 3 测试 1 前言背景 1 1 线程
  • QListWidget右键菜单

    关于QListWidget右菜单的的实现 网上多数资料都没有提到如何使用Qt Creator快速实现 如参考资料 1 2 本文重点介绍此方法 1 槽函数生成 通过Qt Creator的UI设计器将QListWidget控件拖放到主界面中 然
  • 刷题之77. 组合

    题目 给定两个整数 n 和 k 返回范围 1 n 中所有可能的 k 个数的组合 你可以按 任何顺序 返回答案 示例 1 输入 n 4 k 2 输出 2 4 3 4 2 3 1 2 1 3 1 4 来源 力扣 LeetCode 链接 http
  • Pytorch实现Seq2Seq

    前言 Seq2Seq模型用来处理nlp中序列到序列的问题 是一种常见的Encoder Decoder模型架构 基于RNN同时解决了RNN的一些弊端 输入和输入必须是等长的 Seq2Seq的模型架构可以参考Seq2Seq详解 也可以读论文原文
  • MyBatis中的$和#,你知道他们的区别吗?

    转自 MyBatis中的 和 你知道他们的区别吗 下文笔者将讲述MyBatis中的 和 的区别简介说明 如下所示 在MyBatis的xml配置文件中 我们经常看见 和 后面紧跟变量 那么他们有什么区别呢 下文笔者将一一道来 如下所示 1 是
  • C# 爬虫遇到EventStream数据时该怎么获取值

    声明 本文只作学习研究 禁止用于非法用途 否则后果自负 如有侵权 请告知删除 谢谢 今天调用某个网站的接口时发现数据格式是这种的 第一次遇到 正常的应该是这样的才对 有个 响应 然后响应里面是一些返回过来的数据 而这个就很奇怪 没有 响应
  • 07模板学习之模板类的static数据成员的归属问题

    07模板学习之模板类的static数据成员的归属问题 1 模板类的static数据成员的归属问题分析 从上面的图分析 先看类模板中的static int a 若类模板中声明了static数据 那么该a是属于类模板还是属于具体类呢 假设属于类
  • 菜鸟入门Docker

    菜鸟入门Docker 说明 一 什么是Docker 1 虚拟机和Linux容器 二 Docker用途 三 Docker安装 1 设置仓库 2 安装 Docker Engine Community 3 验证安装成功 四 Docker启动与停止
  • Linux必杀(十八):VI、VIM编辑器

    题记 基本上VI共分为3种模式 分别是一般模式 命令行模式和编辑模式 一 一般模式 以Vi打开一个文件就直接进入一般模式了 在这个模式下 可以使用上下左右按键来移动光标 可以删除字符或删除整行 也可以复制 粘贴文件数据 二 编辑模式 在一般
  • Dubbo中的一些常见问题?

    关于dubbo是用的什么协议 在使用dubbo的时候会配置
  • ubuntu 防火墙基本设置

    查看防火墙状态 ufw status 打开防火墙 sudo ufw enable 重启防火墙 sudo ufw reload 开放指定端口 ufw allow 8080
  • 使用C语言打印不同星号图案(矩形 平行四边形 三角形)

    献给大一或大二的学弟学妹们和在自学 C语言的同志们 打印自定义行数的矩形 打印效果 参考代码 include
  • echarts 图表无数据为空时显示“暂无数据”

    如标题所述 我们希望 echarts 图表在没有数据时显示 暂无相关数据 字样 操作 需要对返回的数据做判断 如果有数据则正常显示图表 如果没有数据 我们将此 div 的内容改为文本 暂无相关数据 并设置样式即可 HTML div div
  • 从感知机到Transformer,一文概述深度学习简史

    关注公众号 发现CV技术之美 本文转自机器之心 作者 Jean de Dieu Nyandwi 机器之心编译 这篇文章从感知机开始 按照时间顺序回顾了深度学习的历史 1958 年 感知机的兴起 1958 年 弗兰克 罗森布拉特发明了感知机
  • Java中的异常

    Java中的异常 1 什么是异常 2 异常的类结构 3 运行时异常的特点 4 编译时异常特点 5 对受检异常进行处理 5 1 try catch 捕获处理 5 2 finally子句处理 5 3 finally子句 5 4 throws抛出
  • java案例之制作系统

    java案例之制作系统 案例 需求 定义一个方法 可以接收中奖号码的数组 用户选号的数组 根据命中红球数和篮球数判断最终的结果并输出 分析 系统需要三部份 第一部分是 生成随机产生的7位数双色球数字 其中前6位是红球 第7位是蓝球 红球范围
  • 使用MySQL Workbench建立数据库,建立新的表,向表中添加数据

    点击上图中的 加号 图标 新建一个连接 如上图 先输入数据库的账号密码 帐号默认为root 填好密码后 点击 OK 连接就建立好了 建立完成后 会出现一个长方形的框框 双击它 出现下图所示页面 点击图中的红圈里的按钮 新建一个Schema
  • 图的深度优先遍历(递归与非递归算法)和广度优先遍历

    老师的题目 实验内容 已知某地区的公路网以图表示 图中的顶点表示站点 任意两站点间的路段以带权的边构成的邻接矩阵表示 矩阵中非零元表示两个站点间存在直接的路段 否则没有路段 打开E Test文件夹中的exp06 cpp文件 补充编写所需代码