数据结构-邻接矩阵

news2025/3/13 6:55:40

介绍

邻接矩阵,是表示图的一种常见方式,具体表现为一个记录了各顶点连接情况的呈正方形的矩阵。

假设一共有以下顶点,其连接关系如图所示

那么,怎么表示它们之间的连接关系呢?

我们发现,各条边所连接的都是两个顶点,联想到我们之前学过的能表示两个量直接关系的数据结构,二维数组就是一个不错的选择。

如果i,j两个节点之间存在边联系它们,那么就将graph[i][j]值记为1,如果不存在边联系它们,就记为0.

这样一来,可以表示图中节点关系的邻接矩阵可以具象化为:

由于例图为无向图(即各顶点间路径没有具体指向),所以graph[i][j]与graph[j][i]的值相同,有向图中则需要将两个值单独判断

具体实现

根据输入的各条边的信息(即两个顶点)可以生成邻接矩阵

    cin>>n>>m;
    for (int i=0;i<n;i++) {
        for (int j=0;j<n;j++) {
            graph[i][j]=0;//初始化邻接矩阵
        }
    }
    for (int i=0;i<m;i++) {
        int u,v;
        cin>>u>>v;//读入边信息,更新邻接矩阵
        graph[u][v]=1;
        graph[v][u]=1; //如果是无向图,则还要更新graph[v][u]
    }
    for (int i=0;i<n;i++) {// 输出邻接矩阵
        for (int j=0;j<n;j++) {
            cout<<graph[i][j]<< " ";
        }
        cout<<endl;
    }

根据邻接矩阵来实现各顶点相邻顶点的输出

1)借助结构体来方便记录各顶点的相邻情况

#define MAXN 100 // 最大顶点数
int graph[MAXN][MAXN]; // 邻接矩阵
struct Node{
    int value;
    int num;//记录相邻顶点数目
    Node** neib;//记录相邻顶点
};

2)遍历邻接矩阵,将相邻的顶点添入结构体内,记录相邻顶点

Node* init(int v) {//初始化顶点信息
    Node* temp=(Node*)malloc(sizeof(Node));
    temp->value=v;
    temp->num=0;//邻居数开始为0
    temp->neib=NULL;//记录邻居的指针一开始为空
    return temp;
}
Node** generateGraph() {
    Node** nodes=(Node**)malloc(n*sizeof(Node*));//为结构体分配空间储存每个顶点信息
    for (int i=0; i<=n; i++) {
        nodes[i]=init(i);//初始化每一个顶点代表的结构体
    }
    for (int i=0; i<=n; i++) {
        for (int j=i; j<=n; j++) {
            if (graph[i][j]==1) {//如果两个顶点相邻
                addNeighbor(nodes[i],nodes[j]);
                addNeighbor(nodes[j],nodes[i]); // 无向图需要更新nodes[j]->neib
                m++;
            }
        }
    }
    return nodes;
}

3)为邻接矩阵中为1的两个顶点更新邻居信息

void addNeighbor(Node* temp,Node* neighbor) {
    temp->num++;//邻居数增加
//重新分配指针内存,增加指针数,用来指向新的邻居
    temp->neib=(Node**) realloc(temp->neib,temp->num*sizeof(Node*));
    temp->neib[temp->num-1]=neighbor;//记录新邻居地址
}

这里用realloc来重新分配内存空间

malloc与realloc的不同:

malloc:用于申请一块指定大小的内存空间,并返回指向该空间的地址

realloc:接受两个参数:旧的内存指针与新的大小,用于重新调整一个已经分配完空间的内存大小,并可以将原空间的内容复制到新开辟的空间中,同时释放原内存

4)输出顶点信息

for (int i=0;i<=n;i++) {
        cout<<nodes[i]->value)<<":";
        for (int j=0;j<=nodes[i]->num;j++) {//输出所有相邻顶点
            cout<<nodes[i]->neib[j]->value<<" ";
        }
        cout<<endl;
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1453727.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

春节专题|产业7问:区块链厂商的现在和未来——数字资产厂商

2023转瞬即逝&#xff0c;不同于加密领域沉寂一整年后在年末集中爆发&#xff0c;对于我国的区块链厂商而言&#xff0c;稳中求胜才是关键词&#xff0c;在平稳发展的基调下&#xff0c;产业洗牌也悄无声息的到来。 从产业总体而言&#xff0c;在经过了接近3年的快速发展后&…

Linux命令-netstat

用于端口和服务之间的故障排除 格式&#xff1a;netstat [常用参数] | grep 端口号/进程名称 -n&#xff1a;显示接口和端口的编号 -t&#xff1a;显示TCP套接字 -u&#xff1a;显示UDP套接字 -l&#xff1a;显示监听中的套接字 -p&#xff1a;显示端口对应的进程信息 -a&a…

蓝桥杯:C++队列、优先队列、链表

C普通队列 算法竞赛中一般用静态数组来模拟队列&#xff0c;或者使用STL queue。使用C的STL queue时&#xff0c;由于不用自己管理队列&#xff0c;因此代码很简洁。队列的部分操作如下。 C优先队列 很多算法需要用到一种特殊的队列&#xff1a;优先队列。它的特点是最优数据…

详解自定义类型:枚举与联合体!

目录 ​编辑 一、枚举类型 1.枚举类型的声明 2.枚举类型的优点 3.枚举类型的使用 二、联合体类型(共用体&#xff09; 1.联合体类型的声明 2.联合体的特点 3.相同成员的结构体和联合体的对比 4.联合体大小的计算 5.用联合体判断大小端 三.完结散花 悟已往之不谏&…

从零开始学习数据结构—【链表】—【探索环形链的设计之美】

环形链表 文章目录 环形链表1.结构图2.具体实现2.1.环形链表结构2.2.头部添加数据2.2.1.具体实现2.2.2.测试添加数据 2.3.尾部添加数据2.3.1.具体实现2.3.2.添加测试数据 2.4.删除头部数据2.4.1.具体实现2.4.2.测试删除数据 2.5.删除尾部数据2.5.1.具体实现2.5.2.测试删除数据 …

【leetcode】深搜、暴搜、回溯、剪枝(C++)3

深搜、暴搜、回溯、剪枝&#xff08;C&#xff09;3 一、解数独1、题目描述2、代码3、解析 二、单词搜索1、题目描述2、代码3、解析 三、黄金矿工1、题目描述2、代码3、解析 四、不同路径III1、题目描述2、代码3、解析 一、解数独 1、题目描述 leetcode链接 2、代码 class…

BIG DATA —— 大数据时代

大数据时代 [英] 维克托 迈尔 — 舍恩伯格 肯尼斯 库克耶 ◎ 著 盛杨燕 周涛◎译 《大数据时代》是国外大数据研究的先河之作&#xff0c;本书作者维克托迈尔舍恩伯格被誉为“大数据商业应用第一人”&#xff0c;他在书中前瞻性地指出&#xff0c;大数据带来的信息…

微服务—DSL基础语法与RestClient操作

本博客为个人学习笔记&#xff0c;学习网站&#xff1a;黑马程序员SpringCloud 2021教程 目录 DSL语法 索引库操作 mapping属性 创建索引库 字段拷贝 查询、删除、修改索引库 文档操作 新增文档 查询、删除文档 修改文档 全量修改 增量修改 DSL文档语法小结 Rest…

Mac配置Python3最简单的方法

此文介绍Mac用Anaconda配置Python3 达成效果 能让你目前只装有Python2的Mac装上Python3&#xff0c;同时拥有很多科学计算库 anaconda介绍 anaconda 是一个python的发行版&#xff0c;包括了python和很多常见的软件库, 和一个包管理器conda。常见的科学计算类的库都包含在里…

美国突然致敬中本聪

作者&#xff1a;秦晋 有点看不懂美国的神操作。 2月16日&#xff0c;据《Bitcoin Magazine》报道&#xff0c;比特币的竞争对手、美国参议员伊丽莎白-沃伦对比特币的立场突然180度大转弯。由反对立场转为支持立场。让很多行业媒体出乎意料&#xff0c;甚至惊掉下巴。 报道称&a…

【测试】JUnit

目 录 一.注解二.断言三.用例的执行顺序四.参数化五.测试套件 自动化就是 selenium 脚本来实现的 junit 是 java 的单亓测试工具&#xff0c;只不过我们在实现自动化的时候需要借用一下下 junit 库里面提供的一些方法 引入依赖 Junit 5 <!-- https://mvnrepository.com/a…

php 数组函数

php 数组函数 1. 常用的php数组函数 1. 常用的php数组函数 array_pop() 删除数组中最后一个元素 array_push() 将一个或多个元素插入到数组的末尾 array_keys <?php $arr array("刘岩" > 30, "范冰冰" > 31, "娜扎" > 31);$…

DS:八大排序之堆排序、冒泡排序、快速排序

创作不易&#xff0c;友友们给个三连吧&#xff01;&#xff01; 一、堆排序 堆排序已经在博主关于堆的实现过程中详细的讲过了&#xff0c;大家可以直接去看&#xff0c;很详细,这边不介绍了 DS&#xff1a;二叉树的顺序结构及堆的实现-CSDN博客 直接上代码&#xff1a; …

备战蓝桥杯---图论之最小生成树

首先&#xff0c;什么是最小生成树&#xff1f; 他就是无向图G中的所有生成树中树枝权值总和最小的。 如何求&#xff1f; 我们不妨采用以下的贪心策略&#xff1a; Prim算法&#xff08;复杂度&#xff1a;&#xff08;nm)logm)&#xff1a; 我们对于把上述的点看成两个集…

MAC VSCODE g++编译器无法编译C++11语法的 解决办法(CodeRunner版本)

如果你是使用的 codeRunner 这个插件&#xff0c;就是这个按钮 coderunner的原理大致是&#xff1a;先判断你这是什么语言&#xff0c;然后有一个 code-runner.executorMap 来对应各个语言是用什么执行语句 我发现&#xff0c;我修改之前&#xff08;无法执行C11语法的原因是&a…

智能汽车专题:智能驾驶2023年度报告

今天分享的是智能汽车系列深度研究报告&#xff1a;《智能汽车专题&#xff1a;智能驾驶2023年度报告》。 &#xff08;报告出品方&#xff1a;量子位智库&#xff09; 报告共计&#xff1a;30页 来源&#xff1a;人工智能学派 顶天立地&#xff1a;技术进阶路线明晰 根据…

echarts制作两个柱状图

let colorList[#02ce8b,#ffbe62,#f17373]; let data1 [90,80,70,50] option { title:[{ // 第一个标题text: 环保检测, // 主标题textStyle: { // 主标题样式color: #333,fontWeight: bold,fontSize: 16},left: 20%, // 定位到适合的位置top: 10%, // 定位到适合的位置},{ //…

小程序获取手机号:快速验证和实时验证

概述 小程序手机号快速验证和实时验证都已经开始收费了。 手机号实时验证组件&#xff0c;在每次请求时&#xff0c;平台均会对用户选择的手机号进行实时验证&#xff1b;每次组件调用成功&#xff0c;收费0.04元手机号快速验证组件&#xff0c;平台会对号码进行验证&#xf…

论文阅读_语音识别_Wisper

英文名称: Robust Speech Recognition via Large-Scale Weak Supervision 中文名称: 通过大规模弱监督实现鲁棒语音识别 链接: https://proceedings.mlr.press/v202/radford23a.html 代码: https://github.com/openai/whisper 作者: Alec Radford, Jong Wook Kim, Tao Xu, Greg…

基于协同过滤的时尚穿搭推荐系统

项目&#xff1a;基于协同过滤的时尚穿搭推荐系统 摘 要 基于协同过滤的时尚穿搭推荐系统是一种能自动从网络上收集信息的工具&#xff0c;可根据用户的需求定向采集特定数据信息的工具&#xff0c;本项目通过研究服饰流行的分析和预测的分析和预测信息可视化时尚穿搭推荐系统…