邻接矩阵构造图C++实现

C语言 图的建立(邻接矩阵与邻接表) 5Cinfty。 阅读详情

邻接矩阵

图类的定义

template<typename T>
class MyGraph {
public:
	MyGraph(T a[], int b[][2], int n, int e);//构造函数,初始化具有n个顶点e条边的图,b是一个e×2的二维数组,存储了边的坐标信息
	~MyGraph() { }//析构函数
	T GetVex(int i);//取图中第i个顶点数据信息
	void PutVex(int i, T value);//将图中第i个顶点的数据域置为value 
	void InsertVex(T value);//在图中插入一个顶点,值为value 
	void DeleteVex(int i);//删除图中第i个顶点
	void InsertSide(int i, int j);//在图中插入一条边,其依附的两个顶点的编号为i和j 
	void DeleteSide(int i, int j);//在图中删除一条边,其依附的两个顶点的编号为i和j 
	void PrintSide();//打印边数组
	void DFSTraverse(int v);//深度优先遍历图,从第v个节点开始
	void BFSTraverse(int v);//广度优先遍历图,从第v个节点开始
private:
	void _dfs(const vector<vector<int>>& side, vector<bool>& visit, int v);
	vector<T> vertex;//存放图中顶点的数组	
	vector< vector<int> > side;//存放图中边的数组	
	int vertexNum, sideNum;//图的顶点数和边数
};

图的初始化

初始化具有n个顶点e条边的图,b是一个e×2的二维数组,存储了边的坐标信息,例如b[][2] = { {0,1},{0,2},{0,4},{1,2},{1,3},{1,4},{2,3},{3,4} },说明在边数组side在这些坐标里面的值都为1。这里我的图仅仅是无向图,没有提及有向图,如需变成有向图,仅需在边数组side初始化后不进行对称性赋值即可,其余地方不用变。

//构造函数
template<typename T>
MyGraph<T>::MyGraph(T a[], int b[][2], int n, int e)
{
	vertexNum = n;
	sideNum = e;
	for (int i = 0; i < n; i++)//顶点数组初始化
		vertex.push_back(a[i]);
	//side.push_back(vertexNum,vector<int>(vertexNum, 0)); 吐了,这个一会报错一会不报错
	for (int i = 0; i < vertexNum; i++)//边数组初始化为0,然后再将边数组内的坐标处的值置为1
		side.push_back(vector<int>(vertexNum, 0));
	for (int i = 0; i < sideNum; i++) {
		side.at(b[i][0]).at(b[i][1]) = 1;
		side.at(b[i][1]).at(b[i][0]) = 1;//如果需要有向图的话,将该行注释
	}
}

插入和删除图的顶点

这里使用的vector数组进行了插入和删除

//在图中插入一个顶点,值为value 
template<typename T>
void MyGraph<T>::InsertVex(T value)
{
	vertex.push_back(value);
	vertexNum = vertex.size();
	side.push_back(vector<int>(vertexNum, 0));//边数组添加一行元素
	for (int i = 0; i < vertexNum - 1; i++)//边数组添加一列元素
		side[i].push_back(0);
}

//删除图中第i个顶点
template<typename T>
void MyGraph<T>::DeleteVex(int i)
{
	vertex.erase(vertex.begin() + i);
	vertexNum = vertex.size();
	side.erase(side.begin() + i);//边数组删除该行元素
	for (int j = 0; j < vertexNum; j++)//边数组删除该列元素
		side[j].erase(side[j].begin() + i);
}

深度优先遍历

类似二叉树的前序遍历,唯一不同的是这里多了一个visit数组,用来记录顶点是否被访问过,防止重复访问,如果不是很懂,建议再看看二叉树前序遍历的实现,伪代码如下:

//深度优先遍历图,从第v个节点开始
template<typename T>
void MyGraph<T>::DFSTraverse(int v)
{
	vector<bool> visit(vertexNum, false);
	_dfs(side, visit, v);
}

template<typename T>
void MyGraph<T>::_dfs(const vector<vector<int>>& side, vector<bool>& visit, int v)
{
	cout << vertex.at(v) << " ";
	visit.at(v) = true;
	for (int i = 0; i < vertexNum; i++)
		if (side[v][i] == 1 && visit.at(i) == false)
			_dfs(side, visit, i);
}

广度优先遍历

其实广度优先遍历就是二叉树的层序遍历的演化,唯一不同就是加入了visit数组,防止重复访问,伪代码如下:

//广度优先遍历图,从第v个节点开始
template<typename T>
void MyGraph<T>::BFSTraverse(int v)
{
	vector<bool> visit(vertexNum, false);
	queue<int> myqueue;
	myqueue.push(v);
	visit.at(v) = true;
	while (!myqueue.empty())
	{
		int front = myqueue.front();
		cout << vertex.at(front) << " ";
		for (int i = 0; i < vertexNum; i++) {
			if (visit.at(i) == false && side[front][i] == 1) {
				myqueue.push(i);
				visit.at(i) = true;
			}
		}
		myqueue.pop();
	}
}

全部代码

mygraph.h

#pragma once
#ifndef MYGRAPH_H
#define MAGRAPH_H
#include<iostream>
#include<vector>
#include<queue>
using std::cout;
using std::endl;
using std::vector;
using std::queue;

template<typename T>
class MyGraph {
public:
	MyGraph(T a[], int b[][2], int n, int e);//构造函数,初始化具有n个顶点e条边的图,b是一个e×2的二维数组,存储了边的坐标信息
	~MyGraph() { }//析构函数
	T GetVex(int i);//取图中第i个顶点数据信息
	void PutVex(int i, T value);//将图中第i个顶点的数据域置为value 
	void InsertVex(T value);//在图中插入一个顶点,值为value 
	void DeleteVex(int i);//删除图中第i个顶点
	void InsertSide(int i, int j);//在图中插入一条边,其依附的两个顶点的编号为i和j 
	void DeleteSide(int i, int j);//在图中删除一条边,其依附的两个顶点的编号为i和j 
	void PrintSide();//打印边数组
	void DFSTraverse(int v);//深度优先遍历图,从第v个节点开始
	void BFSTraverse(int v);//广度优先遍历图,从第v个节点开始
private:
	void _dfs(const vector<vector<int>>& side, vector<bool>& visit, int v);
	vector<T> vertex;//存放图中顶点的数组	
	vector< vector<int> > side;//存放图中边的数组	
	int vertexNum, sideNum;//图的顶点数和边数
};

//构造函数
template<typename T>
MyGraph<T>::MyGraph(T a[], int b[][2], int n, int e)
{
	vertexNum = n;
	sideNum = e;
	for (int i = 0; i < n; i++)//顶点数组初始化
		vertex.push_back(a[i]);
	//side.push_back(vertexNum,vector<int>(vertexNum, 0)); 吐了,这个一会报错一会不报错
	for (int i = 0; i < vertexNum; i++)//边数组初始化为0,然后再将边数组内的坐标处的值置为1
		side.push_back(vector<int>(vertexNum, 0));
	for (int i = 0; i < sideNum; i++) {
		side.at(b[i][0]).at(b[i][1]) = 1;
		side.at(b[i][1]).at(b[i][0]) = 1;//如果需要有向图的话,将该行注释
	}
}

//取图中第i个顶点数据信息
template<typename T>
T MyGraph<T>::GetVex(int i)
{
	return vertex.at(i-1);
}

//将图中第i个顶点的数据域置为value 
template<typename T>
void MyGraph<T>::PutVex(int i, T value)
{
	vertex.at(i - 1) = value;
}

//在图中插入一个顶点,值为value 
template<typename T>
void MyGraph<T>::InsertVex(T value)
{
	vertex.push_back(value);
	vertexNum = vertex.size();
	side.push_back(vector<int>(vertexNum, 0));//边数组添加一行元素
	for (int i = 0; i < vertexNum - 1; i++)//边数组添加一列元素
		side[i].push_back(0);
}

//删除图中第i个顶点
template<typename T>
void MyGraph<T>::DeleteVex(int i)
{
	vertex.erase(vertex.begin() + i);
	vertexNum = vertex.size();
	side.erase(side.begin() + i);//边数组删除该行元素
	for (int j = 0; j < vertexNum; j++)//边数组删除该列元素
		side[j].erase(side[j].begin() + i);
}

//在图中插入一条边,其依附的两个顶点的编号为i和j
template<typename T>
void MyGraph<T>::InsertSide(int i, int j)
{
	if (side.at(i).at(j) == 0) {
		sideNum += 1;
		side.at(i).at(j) = 1;
		side.at(j).at(i) = 1;
	}
}

//在图中删除一条边,其依附的两个顶点的编号为i和j 
template<typename T>
void MyGraph<T>::DeleteSide(int i, int j)
{
	if (side.at(j).at(i) != 0){
		sideNum -= 1;
		side.at(i).at(j) = 0;
		side.at(j).at(i) = 0;
	}
}

template<typename T>
void MyGraph<T>::PrintSide()
{
	for (int i = 0; i < vertexNum; i++) {
		for (int j = 0; j < vertexNum; j++)
			cout << side.at(i).at(j) << " ";
		cout << endl;
	}
}

//深度优先遍历图,从第v个节点开始
template<typename T>
void MyGraph<T>::DFSTraverse(int v)
{
	vector<bool> visit(vertexNum, false);
	_dfs(side, visit, v);
}

//广度优先遍历图,从第v个节点开始
template<typename T>
void MyGraph<T>::BFSTraverse(int v)
{
	vector<bool> visit(vertexNum, false);
	queue<int> myqueue;
	myqueue.push(v);
	visit.at(v) = true;
	while (!myqueue.empty())
	{
		int front = myqueue.front();
		cout << vertex.at(front) << " ";
		for (int i = 0; i < vertexNum; i++) {
			if (visit.at(i) == false && side[front][i] == 1) {
				myqueue.push(i);
				visit.at(i) = true;
			}
		}
		myqueue.pop();
	}
}

template<typename T>
void MyGraph<T>::_dfs(const vector<vector<int>>& side, vector<bool>& visit, int v)
{
	cout << vertex.at(v) << " ";
	visit.at(v) = true;
	for (int i = 0; i < vertexNum; i++)
		if (side[v][i] == 1 && visit.at(i) == false)
			_dfs(side, visit, i);
}

#endif // !MYGRAPH_H


测试代码:

#include"mygraph.h"


int main() 
{
	int b[][2] = { {0,1},{0,2},{0,4},{1,2},{1,3},{1,4},{2,3},{3,4} };//边的坐标
	char a[] = { 'A','B','C','D','E' };
	MyGraph<char> mygraph(a, b, 5, 8);
	mygraph.PrintSide();

	cout << endl;
	mygraph.BFSTraverse(0);

	cout << endl;
	mygraph.DFSTraverse(0);

	cout << endl;
	mygraph.InsertVex('F');
	mygraph.PrintSide();

	cout << endl;
	mygraph.DeleteVex(1);
	mygraph.PrintSide();
	return 1;
}

结果:

用C++和邻接矩阵实现图算法——图算法有手就行 给爷爬到爷的收藏夹里面吃灰去 阅读详情

相关推荐

数据结构(C++)—— 图(邻接矩阵)

一、重要概念理解: 完全图(Complate  graph) 在由n个顶点组成的无向图中,若有n*(n-1) / 2条边,则称之为无向完全图。在由n个顶点组成的有向图中,若有n*(n-1) 条边,则称之为有向完全图。 完全图中的边数达到最大。 权(weight) 在某些图中,边具有与之相关的数值,称为权重。权重可以表示从一个顶点到另一个顶点的距离,花费的代价,所需要的时间,次数等。这

Anna的博客 3349

数据结构之图(邻接矩阵实现)(C++)

  一、图的邻接矩阵实现 1.实现了以顶点数组、邻接矩阵为存储结构的图; 2.实现了图的创建(包含有向/无向图、有向/无向网)、顶点/边的增删操作、深度/广度优先遍历的算法; 3.采用顶点对象列表、边(弧)对象列表的方式,对图的创建进行初始化;引用 "ObjArrayList.h"头文件,头文件可参看之前博文“数据结构之顺序列表(支持对象元素)”代码; 4.采用将顶点数组空位的下标索引入...

碣石观海的博客 8170

邻接矩阵实现图的构造 (包含有向图和无向图) 实现 插入或者删除 顶点、边

代码与相关注释如下: #include<iostream> #include<cstring> #include<math.h> #include<stdio.h> #include<stdlib.h> #include<conio.h> #include<vector> #include<queue> #include<stack> using namespace std; const int ma

牛大春の博客 3100

C++实现图—邻接矩阵,邻接表,深度遍历,广度遍历

图的两种实现方式和两种遍历方式,邻接矩阵和邻接表,深度遍历和广度遍历!

终为nullptr 4079

图的实验1——图的邻接矩阵存储实现

图的邻接矩阵存储

lxjune1st61的博客 3297

图像去模糊(二)——Richardson–Lucy算法

Richardson Lucy Algorithm(Richardson-Lucy算法详解及效果实例)

xueruhongchen的博客 3万+

邻接矩阵实现(有向邻接矩阵)、(无向邻接矩阵) 基于C++

邻接矩阵(注意这里实现的有向邻接矩阵图) 图的邻接矩阵存储方式是用两个数组来表示图。一个一维数组存储图中顶点信息,一个二维数组(邻接矩阵)存储图中的边或弧的信息。 设图G有n个顶点,则邻接矩阵是一个nn的方阵,定义为: 看一个实例,下图左就是一个无向图。 从上面可以看出,无向图的边数组是一个对称矩阵。所谓对称矩阵就是n阶矩阵的元满足aij = aji。即从矩阵的左上角到右下角的主对角线为轴,右上角的元和左下角相对应的元全都是相等的。 从这个矩阵中,很容易知道图中的信息。 (1)要判断任意两顶点

qq_40059236的博客 4488

使用fluent计算流噪声_Fluent能够做的事

刚接触到fluent的同学们,应该会比较好奇,fluent能够做些什么事情,和你的研究有没有关联,能不能达到你的目的?如果不弄明白这样一点,前期可能会做很多无用功。 fluent是计算流体力学的软件,是一个工具。这样一个工具发展至今,可以用来模拟的绝不只有流体力学。下面我们依次来说明。首先是流动,fluent提供了非常丰富的流动模型,不仅可以模拟层流,同样还可以模拟...

weixin_28717647的博客 4856

图——有向图、无向图、有向网、无向网的邻接矩阵表示

图的邻接矩阵表示

阿基美德的博客 1万+

innovus 命令每日精要 | 掌控Innovus布线的利器——setNanoRouteMode详解

在数字IC后端设计的复杂世界里,布线优化是至关重要的一步。今天,我来给大家深入讲解Innovus工具中setNanoRouteMode命令的精妙之处,让你轻松驾驭布线策略,提升设计质量。setNanoRouteMode是Innovus中用于配置NanoRoute绕线行为的关键命令。通过其丰富的参数,你可以精细控制布局后阶段的绕线策略、信号完整性优化、工艺适配及设计规则修复等流程。下面,我将按功能分类总结其核心选项,并针对不同场景给出建议。

weixin_50820814的博客 3524

OTN设备核心知识速记

本文章为工作笔记,若有错误,还需大家指正。不定期更新。

Hiddengold的博客 2648

【东华大学oj】邻接矩阵:构造有权图

4个参数的含义:图的类型、结点数、结点值和邻接矩阵中表示结点间没有边的标记(无权图:0,有权图:输入参数定)//返回G中指定顶点u的下一个邻接顶点(相对于v)的位序(顶点集)。//返回G中指定顶点u的第一个邻接顶点的位序(顶点集)。

的博客 1660

T527 uart串口配置导致系统进不去

T527 s_uart串口配置导致系统进不去。

Linux驱动开发工程师,熟悉Linux/Android底层驱动、TP、显示、IIC、网络等通用外设调试适配,Linux上层应用开发。常用平台瑞芯微、全志、恩智浦等。 675

【数据结构】图—图的邻接矩阵存储及度计算

输入图的顶点信息和边信息,完成邻接矩阵的设置,并计算各顶点的入度、出度和度,并输出图中的孤立点(度为0的顶点)不能用别的头文件,但是我可以用string用来存储顶点,因为char型就需要自己写一个strcmp函数,毕竟需要遍历找对应下标不是?按顶点信息输出各顶点的度(无向图)或各顶点的出度 入度 度(有向图)。孤立点的度信息不输出。每行一条边(顶点1 顶点2)或弧(弧尾 弧头)信息。图类型 顶点数 (D—有向图,U—无向图)若没有孤立点,不输出任何信息。无向图的度就是出度和入度相加。

笔记 1455

手把手教你完成YOLOv8分类识别界面搭建,使用Qt6设计YOLOv8分类识别系统,前台系统+后台管理系统开发实战,全网最详细教程

本项目基于YOLOv8分类模型,结合PySide6框架开发了一套图形化分类识别系统,支持图片、视频和摄像头实时检测。系统包含以下功能: 分类识别模块:完成图像/视频目标分类,界面展示检测结果。 用户管理模块:支持登录注册、头像修改、密码重置等功能。 AI问答模块:集成DeepSeek大模型接口,实现流式输出对话。 后台管理系统(第二版新增):管理员可管理用户信息及个人中心。 系统采用MySQL数据库存储用户数据,并提供完整的UI界面与交互逻辑。代码已开源,适用于毕业设计或快速部署场景。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 824

电机驱动器MP6540H应用设计

/ ... 其他初始化函数(SystemClock_Config, MX_GPIO_Init, MX_TIM1_Init, MX_TIM2_Init)需要你根据STM32CubeMX生成或手动编写。// 假设霍尔传感器引脚是 GPIO_PIN_8, GPIO_PIN_9, GPIO_PIN_10。// 低侧U相GPIO引脚。

zhusl6688的博客 656

图的构造(邻接矩阵与邻接表)

两种方式构造下方的图 #include<iostream> #include<vector> using namespace std; struct GraphNode { int label; vector<GraphNode*> neighbors; GraphNode(int x) : label(x) {}; }; //邻接矩阵一般用来表示稠密图 void construct_graph1() { const int MAX_N = 5; //5个顶

Orange1024 301

沁恒CH32V208GBU6读写芯片内部FLASH:代码空间;使用OTA时候的代码空间;保存结构体到FLASH

沁恒CH32V208GBU6读写芯片内部FLASH:代码空间;使用OTA时候的代码空间;保存结构体到FLASH

cheng___yi的博客 555

【东华大学oj】图的邻接矩阵:深度优先遍历

/返回G中指定顶点u的下一个邻接顶点(相对于v)的位序(顶点集)。//返回G中指定顶点u的下一个邻接顶点(相对于v)的位序(顶点集)。//返回G中指定顶点u的第一个邻接顶点的位序(顶点集)。//返回G中指定顶点的位置。

的博客 815

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

数据结构(c++版):邻接矩阵的实现

Graph类是你的城市规划办公室构造函数是你拿到一块空地开始规划addEdges是你在两个区域之间修建道路printGraph是你绘制城市道路地图析构函数是城市废弃后的拆除工作邻接矩阵就像一张巨大的Excel表格,每个单元格记录着两个区域之间的连接情况。虽然对于大型稀疏城市(图)来说有点浪费纸张(内存),但对于小型或高度连接的城市,它能提供一目了然的全貌。通过这个比喻,我们可以更直观地理解图的邻接矩阵表示法及其实现方式。无论是社交网络、交通系统还是神经网络,图结构都在帮助我们理解和建模复杂的关系网络。

2503_90937448的博客 1447

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

【图】邻接矩阵

无向图邻接矩阵的实现

lxylxylxy的博客 1526

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

邻接表:构造有权图(使用头插法)

问题描述 : 目的:使用C++模板设计并逐步完善图的邻接表抽象数据类型(ADT)。 内容:(1)请参照图的邻接矩阵模板类原型,设计并逐步完善图的邻接表ADT。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中。) (2)使用构造函数,构造一个有权图。 注意:DG(有向图), DN(有向网), UDG(无向图), UDN(无向网) 参考函数原型: //构造函数构造一个有权图。6个参数的含义:图的类型、结点数、边数、结点集、边集

Blackoutdragon的博客 1114

邻接矩阵:构造只有结点没有边的图

邻接矩阵:构造只有结点没有边的图

JeredYe的博客 281

实验6:图的实验1 -图的邻接矩阵存储实现

一、实验目的1、熟练理解图的相关概念; 2、掌握图的邻接矩阵的存储方法的实现; 3、学会图的遍历算法 二、实验内容1、自己确定一个简单无向图(顶点数、和相关结点信息)利用邻接矩阵来实现存储。实现图的构造,并完成:    1)用深度优先和广度优秀两种算法对图进行遍历,输出顶点序列数据;    2)以合理的格式,输出各个顶点的邻接点; 2、试设计一个程序,对一个有向简单图,完成上题同样的任务(*)。 ...

Lum_0813的博客 2316

手写图-邻接矩阵

下面是一个完整的C++实现手写邻接矩阵表示图的代码。邻接矩阵是一种常见的图的表示方法,其中矩阵的行和列分别代表图中的顶点,矩阵中的值表示顶点之间是否存在边。

chenmi123321的博客 302

Algorithm第四版算法 C++实现(十二)——使用邻接矩阵法构造无向图

图是一种非常常见的数学模型。图在各种应用中都有非常重要的作用 我们今天要介绍的图叫做无向图,在无向图中,边仅仅起到链接两个顶点的作用。这是一种简单的图模型。 术语解释: 自环:一条链接一个顶点与他自身的边 平行边(无向图):两条及以上关联同一对顶点的无向边 多重图:有平行边的图 简单图:无平行边的图 度数(度):点作为边端点的次数 //邻接矩阵法构造无向图 class graph { private: int v; //顶点数 int e; //边数 std::vector<std::vec

Charlesix59的博客 764
上一篇: 哈夫曼树C++实现
下一篇: 线性表查找
-Gentle-
博客等级 码龄8年 80粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值