数据结构算法—邻接表存储的无向图求连通分量个数

2023-11-19

数据结构算法—邻接表存储的无向图求连通分量个数

邻接表存储结构
typedef struct ArcNode{
	int adjvex;//边指向的顶点
	struct ArcNode *nextarc; // 下一条边的指针 
}ArcNode;
typedef struct VNode{
	int data;//顶点信息 
	ArcNode *fristarc;//该结点的第一条边 
}VNode,AdjList[MAX];
typedef struct {
	AdjList vertices;//头结点数组
	int vexnum,arcnum; // 图的当前顶点数和边数 
}ALGraph;
求连通分量算法思想:

无向图的连通分量: 在离散数学中,几个顶点连在一起,不和其他的顶点互通有无。即构成一个连通分量。 单个顶点也是一个连通分量。
在数据结构中,使用图的遍历算法,从某一个顶点出发,一直寻找与他邻接的顶点。访问过得顶点就标记出来(使用vis[] 数组)。直到 没有邻接的顶点 或者 所有的顶点都访问过了。每结束一次深度遍历就 count(连通分量个数) 加 1 。

tips:

顶点的信息保存在Adjlist 数组中,,输入的顶点值 和 数组中保存的索引值 可能会不同,要统一使用 索引值 所以我写了一个 LocateVex 函数 ,用来寻找 顶点值 对应的 索引值 ,并返回索引值!

完整代码
#include<stdio.h>
#include<stdlib.h>
#define MAX 100
int vis[100];
typedef struct ArcNode{
	int adjvex;//边指向的顶点
	struct ArcNode *nextarc; // 下一条边的指针 
}ArcNode;
typedef struct VNode{
	int data;//顶点信息 
	ArcNode *fristarc;//该结点的第一条边 
}VNode,AdjList[MAX];
typedef struct {
	AdjList vertices;//头结点数组
	int vexnum,arcnum; // 图的当前顶点数和边数 
}ALGraph;
//寻找v1,v2在G中的位置
int LocateVex(ALGraph *G,int v){
	int i;
	for(i=0;i<=G->vexnum;i++)
		if(G->vertices[i].data==v)
			return i;
} 
//创建图
void creatGraph(ALGraph *G){
	int i,j,k,m,n;
	ArcNode *s;
	printf("请输入图的顶点数和边数:");
	scanf("%d%d",&G->vexnum,&G->arcnum);
	getchar();//吃掉回车
	printf("请依次输入顶点集");
	for(i=0;i<G->vexnum;i++){
		scanf("%d",&G->vertices[i].data);
		getchar();
	}
	for(i=0;i<G->vexnum;i++)
		G->vertices[i].fristarc=NULL;
	for(k=0;k<G->arcnum;k++){
		printf("请输入一条边的两个结点:");
		scanf("%d%d",&i,&j);
		m=LocateVex(G,i);// 不能用输入的结点信息,这里要使用 结点信息数组中的 索引值,不然会出错 
		n=LocateVex(G,j);
		s=(ArcNode*)malloc(sizeof(ArcNode));// 头插法 建立链表 
		s->adjvex=j;
		s->nextarc=G->vertices[m].fristarc;
		G->vertices[m].fristarc=s;
		//生成对称结点   无向图  
		s=(ArcNode*)malloc(sizeof(ArcNode));
		s->adjvex=i;
		s->nextarc=G->vertices[n].fristarc;
		G->vertices[n].fristarc=s;
	}
}
void readGraph(ALGraph G){ //深度递归 
	int i,j;
	ArcNode *p;
	for(i=0;i<G.vexnum;i++){
		printf("%d : ",G.vertices[i].data);// 结点信息保存在 data 域中    
		for(p=G.vertices[i].fristarc;p;p=p->nextarc)
			printf(" %d",p->adjvex);
		printf("\n");
	}
}
// 求连通个数   深度优先算法 
void DFS(int x,ArcNode *p,ALGraph *G){
	vis[x]=1;  // 将 x 标记已访问   
	for(p = G->vertices[x].fristarc;p;p=p->nextarc){ //找到 链表  依次访问    和 readGraph 的for循环一样  深度递归算法 
		if(!vis[LocateVex(G,p->adjvex)]){ // p->adjvex 当前结点未访问  
			int i=LocateVex(G,p->adjvex); 
			DFS(i,p,G); 
		}
	}
}
int main(){
	ALGraph G;
	creatGraph(&G);
	readGraph(G);
	int count=0;
	for(int i=0;i<G.vexnum;i++)
		vis[i]=0;
	ArcNode *p;
	for(int i=0;i<G.vexnum;i++){
		p = G.vertices[i].fristarc; 
			if(!vis[i]){
				DFS(i,p,&G);
				count++;  // 每当深度调用完毕,意味着:走到头了。是一个连通分量,再判断 有没有未被访问的结点,如果有继续,没有循环结束。count即为连通分量个数 
			}
	}
	printf("连通分量个数为:%d",count);
}

运行结果实例:
请输入图的顶点数和边数:6 3
请依次输入顶点集
1 2 3 4 5 6
请输入一条边的两个结点:1 3
请输入一条边的两个结点:2 4
请输入一条边的两个结点:4 6
1 :  3
2 :  4
3 :  1
4 :  6 2
5 :
6 :  4
连通分量个数为:4
--------------------------------
Process exited after 11.75 seconds with return value 0
请按任意键继续. . .

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

数据结构算法—邻接表存储的无向图求连通分量个数 的相关文章

随机推荐

  • Java学习

    Java之AJAX概念和实现方式 开发工具与关键技术 MyEclipse 10 java 作者 刘东标 撰写时间 2019 06 12 1 概念 Asynchronous JavaScript And XML 异步的JavaScript和X
  • 睿智的seq2seq模型2——利用seq2seq模型实现英文到法文的翻译

    睿智的seq2seq模型2 利用seq2seq模型实现英文到法文的翻译 学习前言 seq2seq简要介绍 英文翻译到法文的思路 1 对英文进行特征提取 2 将提取到的特征传入到decoder 3 将 t 作为起始符预测第一个字母 4 逐个字
  • 计算资源合并模式——云计算架构常用设计模式

    背景 云计算的解决方案中 最初设计可能有意遵循关注点分离的设计原则 把操作分解为独立的计算单元以便可以单独托管和部署 然而 虽然这种策略可以帮助简化解决方案的逻辑实现 但是在同一个应用程序中要部署大量的计算单元 这会增加运行时的托管成本 并
  • 性能测试大致分为以下六种

    性能测试大致分为以下六种 第一种是Benchmark 标杆测试 又叫基准测试 主要是测试一些基础数据 给进一步建立性能模型提供依据 一般测试人员按照1并发用户来执行脚本 校验脚本正确与否 为之后的压力测试和负载测试做准备 第二种是Load
  • 传奇修改数据库后服务器异常,DBserver提示物品数据库加载错误的解决方法

    DBserver exe程序是传奇服务端 什么是传奇服务端 中负责人物数据库处理的重要程序 也是我们运行服务端时第一个启动的程序 但由于现在的数据库名不统一还有服务端路径的不同 经常在运行时提示 Exception 物品数据库加载错误 在我
  • centos7 RTNETLINK answers: File exists 解决办法

    首先说一下本人遇到的问题 我是通过克隆虚拟机安装的服务器 已将 etc sysconfig network scripts ifcfg eno16777736 的UUID这一行删除 因为每张网卡的mac地址是不一样的 所以UUID也是不一样
  • 全卷积神经网络( FCN ):语义分割深度模型先驱

    语义分割 简单地说 分割就是抠图 语义分割 是像素级别地给物体分类 现在ps已经集成了很多自动分割的功能 摄像头采集到车前景象 通过模型分析 我们可以自动筛选出地面 交通线 人行道 行人 建筑 树 以及其他基础设施 在上图 我们可以看到地面
  • MyBatis 的基本使用、增删改查(一)

    1 ORM Mybatis ORM 对象关系映射 这个通俗点讲其实就是数据库的表和实体类相互映射的关系 这个了解一下就行 不重要 Mybatis 基于java的持久层框架 2 Mybatis 的入门使用 这边没有集成spring sprin
  • Qt 集成Web 的内容

    文章目录 Qt 集成Web 的内容 Qt 中的WebEngine Qt和HTML JavaScript混合应用程序 Qt WebEngine 概述 Qt WebEngine 架构 Qt WebEngine Widgets 模块 Qt Web
  • python远程文件管理系统_python 读取远程服务器文件

    几个提高工作效率的Python内置小工具 在这篇文章里 我们将会介绍4个Python解释器自身提供的小工具 这些小工具在笔者的日常工作中经常用到 减少了各种时间的浪费 然而 却很容易被大家忽略 每当有新来的同事看到我这么使用时 都忍不住感叹
  • openvino+yolov5的检测优化及其在考勤机上的应用

    openvino yolov5的检测优化及其在考勤机上的应用 1 简介 2 安装yolov5 3 配置Pytorch环境 1 在开始界面中打开Anaconda Prompt 2 输入命令 4 配置到Pycharm 1 打开Pycharm 2
  • 多维时序

    多维时序 MATLAB实现GA GRU遗传算法优化门控循环单元多变量时间序列预测 目录 多维时序 MATLAB实现GA GRU遗传算法优化门控循环单元多变量时间序列预测 效果一览 基本介绍 程序设计 参考资料 效果一览 基本介绍 多维时序
  • ubuntu16.04踩坑笔记--ubuntu循环登录问题

    感觉自己有毒 在没有预兆的情况下 ubuntu登录界面循环登录 无法进入桌面 具体表现为登录密码输入后 黑屏一下继续回到登录界面 然后循环 在网上找到很多方法 比如 1 检查 Xauthority属于我的所有权 而不是root 包括删掉和权
  • failed to execute goal org.apache.maven.plugins:maven-archetype-plugin错误解决方法

    使用maven创建project时碰到如下错误 D codes JSF gt mvn archetype create DgroupId com tutorialspoint test DartifactId helloworld Darc
  • 把openssh升级到8.1版本

    把openssh升级到8 1版本各种坑都能解决无敌 下载相应的软件包 yum install wget gcc y yum group install Development Tools y yum install y zlib devel
  • 删除链表的倒数第n个节点

    题目 Given a linked list remove the n th node from the end of list and return its head For example Given linked list 1 gt
  • 形象易懂讲解算法II——压缩感知

    形象易懂讲解算法II 压缩感知
  • Qt5.12.2交叉编译并移植程序到ARM过程记录

    交叉编译 在系统A中编译出在要系统B中运行的环境 程序 编译工具 x9 gcc linaro 5 5 0 2017 10 x86 64 arm linux gnueabihf 1 将编译工具拷贝到 opt 文件夹 2 下载Qt源代码 解压
  • 【云原生】Docker 详解(三):Docker 镜像管理基础

    Docker 详解 三 Docker 镜像管理基础 1 镜像的概念 镜像可以理解为应用程序的集装箱 而 Docker 用来装卸集装箱 Docker 镜像含有启动容器所需要的文件系统及其内容 因此 其用于创建并启动容器 Docker 镜像采用
  • 数据结构算法—邻接表存储的无向图求连通分量个数

    数据结构算法 邻接表存储的无向图求连通分量个数 邻接表存储结构 typedef struct ArcNode int adjvex 边指向的顶点 struct ArcNode nextarc 下一条边的指针 ArcNode typedef