当前位置: 首页 > news >正文

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

图的矩阵表示:用数字编织的关系网

图(Graph)是计算机科学中一种重要的数据结构,它像一张错综复杂的蜘蛛网,能够清晰地表示事物之间的关系。让我们通过一个C++实现的邻接矩阵图类,来探索这种数据结构的奥秘。

图的骨架:邻接矩阵

想象你有一张城市地图,每个交叉路口是一个节点,道路则是连接这些节点的边。邻接矩阵就像一张表格,记录着每个路口到其他路口是否有道路相连。

class Graph
{
private:int topNums;int** edges;
public:Graph(int topNums);~Graph();void addEdges(int u, int v, int w);void printGraph();
};

这个Graph类就像是一个城市规划师的工具箱,topNums是城市中路口的数量,edges则是记录道路信息的表格。

建造城市:构造函数

构造函数就像是在一片空地上规划城市的基础设施:

Graph::Graph(int topNums)
{this->topNums = topNums;edges = new int* [topNums];for (int i = 0; i < topNums; i++){edges[i] = new int[topNums];for (int j = 0; j < topNums; j++){edges[i][j] = inf;}}
}

这个过程就像:

  1. 决定城市要有多少个路口(topNums
  2. 为每个路口准备一个记录本(edges[i] = new int[topNums]
  3. 初始化时,假设所有路口之间都没有道路(edges[i][j] = inf

铺设道路:添加边

void Graph::addEdges(int v, int u, int w)
{edges[v][u] = w;
}

这个方法就像是在两个路口之间修建一条道路。v是起点,u是终点,w是道路的长度或权重。如果是无向图,我们通常需要同时设置edges[u][v] = w,就像修建双向车道。

查看城市规划:打印图

void Graph::printGraph()
{for (int i = 0; i < topNums; i++){for (int j = 0; j < topNums; j++){cout << edges[i][j]<<" ";}cout << endl;}
}

这个方法就像打印出一张城市道路连接表,让你一眼看清哪些路口之间有道路相连,以及道路的长度。

清理现场:析构函数

Graph::~Graph()
{for (int i = 0; i < topNums; i++){delete[]edges[i];}delete[] edges;
}

当城市不再需要时,析构函数负责清理所有分配的内存,就像拆除不再使用的道路和路口。

构建一个示例图

int main()
{Graph g(6);g.addEdges(1, 3, 2);g.addEdges(1, 4, 5);g.addEdges(3, 2, 1);g.addEdges(2, 4, 1);g.addEdges(0, 3, 1);g.addEdges(4, 5, 1);g.printGraph();return 0;
}

这段代码构建了一个有6个节点的图,并添加了6条边。就像在一个有6个路口的城市中修建了6条道路。

二维指针数组的基本概念:

二维指针数组本质上是一个"指针的指针"结构。它就像一栋办公楼:

  • 整栋楼是一个一级指针数组​(int** edges
  • 每一层楼是一个二级指针数组​(int* edges[i]
  • 每个办公室存储着一个具体的整数值(edges[i][j]
int** edges; // 声明一个二维指针数组

内存分配过程详解

在构造函数中,我们为这个二维数组分配内存:

edges = new int* [topNums]; // 1. 分配第一维:创建指针数组
for (int i = 0; i < topNums; i++)
{edges[i] = new int[topNums]; // 2. 为每个指针分配第二维数组for (int j = 0; j < topNums; j++){edges[i][j] = inf; // 3. 初始化每个元素}
}

这个分配过程可以分为三个步骤:

  1. ​分配第一维(楼层建设)​​:

    • new int* [topNums] 创建了一个包含topNums个指针的数组
    • 就像建造一栋有topNums层的大楼
  2. ​分配第二维(每层办公室)​​:

    • edges[i] = new int[topNums] 为每一层创建包含topNums个整数的数组
    • 就像在每层楼建造topNums个办公室
  3. ​初始化元素(办公室准备)​​:

    • edges[i][j] = inf 将每个位置初始化为无穷大(表示初始时无边)
    • 就像给每个办公室贴上"空置"标签

内存布局可视化

假设topNums=3,内存布局如下:

edges (int**)
│
├── edges[0] (int*) → [inf, inf, inf]
├── edges[1] (int*) → [inf, inf, inf]
└── edges[2] (int*) → [inf, inf, inf]

这种布局不是连续的二维数组,而是指针数组指向多个独立的一维数组。这与传统的栈上二维数组(如int edges[3][3])在内存布局上有本质区别。

邻接矩阵的优缺点

邻接矩阵就像一张完整的城市道路规划表:

优点:​

  • 查找两个节点是否相邻非常快速(O(1)时间复杂度)
  • 适合表示稠密图(边很多的情况)
  • 容易实现各种图算法

缺点:​

  • 空间复杂度高(O(n²))
  • 对于稀疏图(边很少的情况)会浪费大量空间

比喻总结

想象你是一位城市规划师:

  • Graph类是你的城市规划办公室
  • 构造函数是你拿到一块空地开始规划
  • addEdges是你在两个区域之间修建道路
  • printGraph是你绘制城市道路地图
  • 析构函数是城市废弃后的拆除工作

邻接矩阵就像一张巨大的Excel表格,每个单元格记录着两个区域之间的连接情况。虽然对于大型稀疏城市(图)来说有点浪费纸张(内存),但对于小型或高度连接的城市,它能提供一目了然的全貌。

通过这个比喻,我们可以更直观地理解图的邻接矩阵表示法及其实现方式。无论是社交网络、交通系统还是神经网络,图结构都在帮助我们理解和建模复杂的关系网络。

http://www.dtcms.com/a/552768.html

相关文章:

  • 在华为TaiShan 200系列服务器基于CentOS 7.6/7.7创建虚拟机
  • Parallels Desktop 26.1.1 for Mac 秋叶QiuChenly中文解锁直装版,最好用的macOS虚拟机
  • Linux chmod权限速成指南
  • 企业网站建设市场的另一面写字就能赚钱做网站
  • 【已解决】解决CondaVerificationError:PyTorch安装包损坏问题
  • UI引擎里AceAbility::OnStart函数1
  • 卸载工具uninstall tool下载安装教程(附安装包)绿色版
  • Bug: 升级内核后有线网络无法使用
  • 帕金森症手绘图像分类数据集
  • 本地生活曝光缺失?GEO语义锚点来救场
  • Rust开发之Result枚举与?运算符简化错误传播
  • Rust专项——其他集合类型详解:BTreeMap、VecDeque、BinaryHeap
  • 软件开发模式架构选择
  • 网站开发设计注册注册小程序
  • Git命令(三)
  • Spring Security 新手学习教程
  • 72.是否可以把所有Bean都通过Spring容器来管
  • DevExpress WPF中文教程:Data Grid - 如何使用虚拟源?(四)
  • 车载软件需求开发与管理 --- 需求收集与整理
  • [linux仓库]线程控制[线程·叁]
  • 从工行“余额归零”事件看CAP定理:当金融系统在一致性与可用性之间做出选择
  • Java的stream使用方案
  • 给网站做视频怎么赚钱电影网站系统源码
  • React Server Components 进阶:数据预取与缓存
  • MR30分布式I/O助力物流分拣系统智能化升级
  • 当UAF漏洞敲响提权警钟:技术剖析与应对之道
  • Flink(用Scala版本写Word Count 出现假报错情况解决方案)假报错,一直显示红色报错
  • Smartbi 10 月版本亮点:AIChat对话能力提升,国产化部署更安全
  • 网站备案单位商业网站源码免费下载
  • 外贸网站经典营销案例搭建服务器做网站