邻接矩阵和邻接表

2023-05-16

图的概述和存储结构(一)


文章目录

  • 前言
  • 一、图的概述
    • 1)图的分类
    • 2)图的要素
  • 二、图的存储结构
  • 三、邻接矩阵
  • 四、邻接表


前言

有一种说法是程序是由数据结构和算法组成的,这很能体现出数据结构在编码中的重要性。而代码优化的能力也是区别有基础的程序员和码农的重要标准,所以对于这一块的学习一定要稳重与细致,每一个章节都要实打实敲出能够实现该种结构的代码才算完成。

数据结构的学习本质上是让我们能见到很多前辈在解决一些要求时间和空间的难点问题上设计出的一系列解决方法,我们可以在今后借鉴这些方法,也可以根据这些方法在遇到具体的新问题时提出自己的解决方法。(所以各种定义等字眼就不用过度深究啦,每个人的表达方式不一样而已)在此以下的所有代码都是仅供参考,绝对不是唯一的答案,任何一种操作能达到相同的结果,只要逻辑上能行的通,复杂度上差不多,是无所谓怎么去实现最后的功能的。


一、图的概述

图是由两个集合组成的V代表顶点集合 E代表边集合(一个顶点偶数对)
在这里插入图片描述

1)图的分类

1.简单图
在图当中如果不存在顶点到其自身的边 且边不重复 的图叫做简单图;

2.无向图与有向图
没有方向的图是无向图、每条边都有方向的是有向图;

3.完全图
如果图中任意两个节点之间都存在一条边 称之为完全图。

2)图的要素

1.端点和邻接点
在无向图中存在(i,j)那么顶点i和顶点j是两个端点 且 i和j互为邻接点;
在有向图中(i,j)那么顶点i是起点,顶点 j是终点;

2.度
无向图中顶点具有的边的数目就是度
有向图中
入度 以该顶点进入边的数目,
出度 以该顶点出去边的数目;

3.子图
有一个图是另一个图的顶点的子集,并且边的关系一致;

4.路径 路径长度
对于这个图
在这里插入图片描述

ADE是一条路径 很明显路径不止一条
而路径长度,是A到D到E边的数目

5.连通 连通图 连通分量
如果两个节点之间有路径 那么就是连通的如果任意节点连通 那么就是连通图
一个无向图中 一个极大连通子图(再多一个节点就连通不上了) 就是连通分量
一个有向图中 一个极大连通子图(再多一个节点就连通不上了) 就是强连通分量

6.稠密图 和 稀疏图
通常认为n个节点的图边数为nlogn那么小于nlogn的边叫稀疏图大于的叫稠密图
事实上视具体情况而定

7.权 和 网
图中每一条边所对应的数字 就叫权值(可以理解为对于工期 需要的时间)
对于带权的图 就称网

8.连通图的生成树
就是一个极小连通图(再减去一条边就不连通了)
生成树不止一个

二、图的存储结构

图的存储分为:邻接矩阵 邻接表 十字链表 邻接多重表 边集数组

三、邻接矩阵

在这里插入图片描述
对于如此一个无向图而言 我们应该考虑怎么样去实现存储图的顶点和边的信息,

实际上我们可以用一个一维数组存储顶点的信息 和 二维数组来边的信息

在这里插入图片描述这是一个二维数组的具现化表格,表头代表的是顶点的下标

对一个非带权的图 0代表没有边 1代表有边,值得注意的是在实际中顶点指向自己的边是没有意义的,即对角线恒为0

如果是带权的图 初始化为0或者为一个不可能的值(如65535

那么对如此一个无向图,可以得到以下表格
在这里插入图片描述
因为是无向图,顶点i既连接顶点j,又被顶点j连接,所以无向图是对称的关系

那么我们只要把上表的数据写入二维数组就是邻接矩阵

#include <stdio.h>
#include <stdlib.h>
#define MaxVertices 100
//邻接矩阵
typedef struct AdjacentMatrix
{
    //顶点集
    int Vertices[MaxVertices];
    //边集
    int Edge[MaxVertices][MaxVertices];
    //顶点数 边数
    int numV, numE;
}AdjMatrix;

void creategrahp(AdjMatrix* G)
{
    int n, e;//n代表顶点数 e代表边数
    int vi, vj;//vi vj代表边的两个顶点对
    printf("要输入的顶点数和边数\n");
    scanf_s("%d%d",&n,&e);
    G->numV = n; 
    G->numE = e;
    //图的初始化
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < n; j++)
        {
            if(i == j)
            {
                //一个非带权的图 0代表没有边 1代表有边
                //边不指向自己 即对角线为0
                G->Edge[i][j] = 0;
            }
            else
            {
                //如果是带权的图 初始化为0或者为一个不可能的值
                G->Edge[i][j] = 65535;
            }
        }
    }
    //将顶点存入数组
    for(int i = 0; i < G->numV; i++)
    {
        printf("请输入第%d个节点的信息\n",i + 1);
        scanf_s("%d", &G->Vertices[i]);
    }
    //输入边的信息
    for(int i = 0; i< G->numE; i++)
    {
        //如果输入的是顶点的值 需要从顶点集中查找对应的下标 
        //如果是带权图 还要输入权的信息
        printf("请输入边的信息Vi,Vj\n");
        scanf_s("%d%d",&vi,&vj);
        G->Edge[vi][vj] = 1;
        //如果是带权图 等于权值
        //如果是有向图 就不对称
        //如果是无向图 矩阵对称
        G->Edge[vj][vi] = 1;
    }
}

四、邻接表

对于邻接矩阵来说如果图的边比较少,那么是空间浪费的,而邻接表弥补了这个缺点

邻接表
数组(顶点集)+链表(边集)的形式

顶点集
在这里插入图片描述

#define MAXVEX 100//表示顶点的数目
typedef struct VertexNode
{
    //存放信息的值
    char data;
    //边表的头指针
    EdgeNode* first;
}VertexNode;

边集
在这里插入图片描述

//边表的结构
typedef struct EdgeNode
{
    //邻接的点所对应的下标
    int adjvex;
    //指向下一个的指针
    struct EdgeNode* Next;
    //权值
    int weight;
}EdgeNode;

还是对这么一个无向图而言
在这里插入图片描述
由上述的数组(顶点集)+链表(边集)我们可以画出以下关系图
在这里插入图片描述
我把第一排单独拿出细说。
从无向图中我们可以看出节点V0与 V1 V2 V3三个节点连通,那么对于V0的顶点集来说,记录的是V0的数据和从V0出发指向其邻接点的指针(因为是无向图所以指针firstarc指向的第一个邻接点 可以是无先后顺序的);

V0的边集应该记录的这个邻接的点所对应的下标、指向下一个邻接点的指针、和权值(这里没有)

那么很容易能得到这张关系图,而其他的节点是一样的
在这里插入图片描述

#include<stdio.h>
#include<stdlib.h>
//邻接表
#define MAXVEX 100//表示顶点的数目
//边表的结构
typedef struct EdgeNode
{
    //邻接的点所对应的下标
    int adjvex;
    //指向下一个的指针
    struct EdgeNode* Next;
    //权值
    int weight;
}EdgeNode;
//顶点表的结构
typedef struct VertexNode
{
    //存放信息的值
    char data;
    //边表的头指针
    EdgeNode* first;
}VertexNode;
//邻接表的抽象结构
typedef struct
{
    //顶点集合数组
    VertexNode adjlist[MAXVEX];
    //顶点的数量 边的数量
    int numV, numE;
}Adjlist;

//以无向图构建邻接表
void creatadjlist(Adjlist* G)
{
    printf("输入顶点数和边数\n");
    scanf("%d%d", &G->numV, G->numE);
    //输入顶点信息
    for(int i = 0; i < G->numV; i++)
    {
        scanf("%c", &G->adjlist[i]);
        getchar();//清空缓存区
        G->adjlist[i].first = NULL;
    }
    //输入边的信息
    //接收边的顶点偶数对的信息
    int vi, vj;
    for(int i = 0; i < G->numE; i++)
    {
        scanf("%d%d", &vi, &vj);
        getchar();
        EdgeNode* e1 = (EdgeNode*)malloc(sizeof(EdgeNode));
        //判断是否创建成功
        if(e1 == NULL)
        {
            printf("MALLOC FAIL\n");
            exit(-1);
        }
        else
        {
            //头插
            //这里的下标 就用vi vj表示
            e1->adjvex = vj;
            e1->Next = G->adjlist[vi].first;
            G->adjlist[vi].first = e1;
            //如果是无向图 反向插入一遍
            EdgeNode* e2 = (EdgeNode*)malloc(sizeof(EdgeNode));
            e2->adjvex = vi;
            e2->Next = G->adjlist[vj].first;
            G->adjlist[vj].first = e2;
        }
    }
}

而对于一个有向图而言,有向图的邻接表代表出度,逆邻接表表达入度
在这里插入图片描述

对于带权图一个元素代表出度顶点的下标,另一个元素代表边的权值

二者在代码上与无向图的邻接表没什么大的区别

邻接表可以说解决了邻接矩阵空间浪费的问题,并且邻接表本身并没有什么大的缺陷,如果说有缺点,那么是对于有向图而言对同时表示一个顶点的出度和入度麻烦,因为需要有邻接表和逆邻接表同时表示,那么有没有一种结构能解决这个问题呢?且听下回分解

还是那句话代码仅供参考,不是唯一答案

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

邻接矩阵和邻接表 的相关文章

  • AirSim相机、IMU内外参分析(VIO、vSLAM)

    作者 朱贞欣 xff0c 公ZH xff1a SLAM学习er 文章目录 0 引入1 世界坐标系2 IMU2 1 IMU数据生成2 2 关于IMU噪声 3 相机3 1 相机外参3 2 内参 0 引入 假设你想通过AirSim获取仿真数据运行
  • C++ cout输出小数位数

    方法一 xff1a 使用setiosflags span class token macro property span class token directive hash span span class token directive
  • kubeadm init 运行时kebelet启动失败问题

    最近在部署kebeedge xff0c 需要先在云服上部署k8s xff0c 期间通过kubeadm init config的方式进行master的部署 xff0c 记录一下遇到的kubelet相关的错误 在通过kubeadm init c
  • 2288hv5超融合服务器 数码管报888

    问题现象 2288hv5超融合服务器 xff0c 前面板数码管报888 xff0c 电源灯黄灯闪烁 xff0c 开不了机 xff0c ibmc网络是通的 xff0c 但是web网页打不开 问题原因 iBMC的版本过低 xff0c iBMC在
  • 跟我一起写操作系统(二)——史上最简单的内核

    跟我一起写操作系统 二 史上最简单的内核 转载注明出处 xff1a http www cnblogs com lucasysfeng p 4847662 html 上一讲地址 xff1a http www cnblogs com lucas
  • k8s中文文档

    http www cnblogs com huangzhenyou p 8066145 html k8s概念比较多 xff0c 有什么概念的疑惑的推荐看k8s中文文档 me的环境 操作系统 xff1a centos7 docker xff1
  • 阿里云 CentOS7 安装图形化界面 。安装图形化界面看这一篇就够了。

    阿里云centos7 下执行eclipse 响应学校老师的要求安装eclipse用于与hadoop的操作 在这之前想过两种方法来解决服务器无图形化界面 xff0c 来操作eclipse 1 在主机上下载eclipse把需要编译的代码编译成j
  • 把ESXi中的虚拟机通过OVA/OVF导出的方式迁移到Proxmox 5

    一 前言 之前发现ESXi是免费的时候 xff0c 非常兴奋地把几台服务器都装上了 xff0c 用着确实还行 xff0c 但是用久了之后就发现 xff0c 很多高端功能需要进一步付费才能使用 xff0c 比如HA等 另外就是它还有很多局限性
  • PX4 ThoneFlow光流使用

    PX4官方光流介绍 xff1a PMW3901 Based Flow Sensors PX4 User Guide 与飞控连接 接线 xff1a G接GND xff1b V接3 3V xff1b T是TX接飞控的RX口 xff1b Y接地开
  • Ubuntu PX4无人机仿真环境配置

    目录 一 VM虚拟机安装ubuntu18 04 1 VMware安装 2 新建虚拟机 二 Ubuntu系统配置 1 更改软件安装源 2 安装中文输入法 三 PX4环境搭建 1 安装git 2 下载px4源码 3 安装ROS 4 安装MAVR
  • larave5安装过程分享-MAX OSX版本

    MAC上的平台是XAMPP xff0c 自带的版本低 我用的是XAMPP MAC版本 一 本地php环境配置 which php php xff0d v xff5c php xampp php PASH 61 34 xff0f applic
  • PX4二次开发 创建进程

    目录 一 创建进程 二 仿真测试 PX4官方手册 xff1a Module Template for Full Applications PX4 User Guide 编写参照PX4源码 src templates xff1a PX4 Au
  • 【Matlab】Matlab基础绘图整理

    Matlab基础绘图整理 一张图绘制多个子图在图片文本中添加希腊字母和特殊字符其他常用函数限制坐标轴范围添加坐标轴说明添加图例修改线条类型 标记修改线条粗细 一张图绘制多个子图 主要命令 xff1a figure 第几张图 subplot
  • PX4 磁罗盘干扰分析

    磁罗盘干扰分析 推力与磁场关系正常情况干扰情况与推力相关解决方法 与推力不相关 罗盘补偿操作流程获取用于分析的日志分析日志调整罗盘补偿参数 推力与磁场关系 无人机上的电机电流会干扰无人机上搭载的磁罗盘 xff0c PX4官方提供了一些方式
  • 【C++】进制

    目录 一 进制转换1 十进制转二进制2 十进制转八进制 xff08 同上 xff09 3 二进制转八进制4 二进制转十六进制5 八进制转二进制6 十六进制转二进制 二 位运算1 原码 反码 补码2 位运算符3 变换操作 一 进制转换 1 十
  • Ubuntu20.04安装ROS2+ROS2-PX4框架搭建

    目录 Ubuntu20 04安装ROS2Set localeSetup SourcesInstall ROS2 packageEnvironment setup测试 ROS2 PX4框架搭建Install PX4Install ROS2Se
  • Jetson Nano利用ROS2通过MicroDDS与PX4通讯

    目录 Jetson Nano安装Ubuntu20 04Ubuntu20 04 配置ROS2环境Pixhawk配置Jetson Nano上MicroDDS Agent配置及和pixhawk通讯 PX4在V1 14及后续版本中 xff0c 将原
  • 用速腾RS16跑LeGO-LOAM

    版权声明 xff1a 本文为博主原创文章 xff0c 遵循 CC 4 0 BY SA 版权协议 xff0c 转载请附上原文出处链接和本声明 本文链接 xff1a https blog csdn net Zed Of Zoe article
  • Visual Studio 2017环境配置MPI v9.0 并行编程环境

    目录 第一步 xff1a 下载安装mpi 官网 xff1a http www mpich org windows版官网 xff1a https msdn microsoft com en us library bb524831 v 61 v

随机推荐

  • 学习java基础的心得感悟

    学完java基础 xff0c 对java面向对象的思想有更加深刻的认识了 xff0c 从学习java语言概述到最后网络编程IDE的使用 xff0c 时间用了1个月零9天 xff0c 上课时间28天 xff0c 回首感觉快又感觉漫长 xff0
  • 如何使用SQL批量替换数据库特定字段中部分特定数据

    1 替换数据库特定字段中部分特定数据的SQL语句 SQL语句 xff1a update 表名 set 字段名 61 replace 字段名 原字符串 需要替换成的字符串 以将表exam major中的字段pos2019中的数据 50 替换成
  • 阿里云ubuntu16.04 server 配置方案 1 配置桌面环境

    首先为服务器配置一个桌面系统 升级一下哦 xff01 span class hljs built in sudo span apt get update span class hljs built in sudo span apt get
  • Xshell远程连接华为云服务器

    Xshell远程连接华为云服务器 一 关于华为云1 什么是云服务器2 为什么使用华为云3 我的华为云体验 二 控制台操作 1 设置密码 2 开放端口 3 切换系统 三 Xshell操作 1 下载Xshell和Xftp2 连接云服务器 一 关
  • 校园网网络连接反复断开又连接是什么原因?

    网络连接反复断开又连接是什么原因 xff1f 原因可能跟ARP攻击或擅自使用P2P终结者等攻击软件有关 因为校园内多个楼宇已部署防ARP攻击网络设备 xff0c 只要判断用户计算机感染ARP或使用P2P终结者 网络执法官 聚生网管等软件攻击
  • xuperchain源码分析-启动过程

    xuperchain的启动分为两个比较大的过程 xff0c 一个是节点的初始化 xff0c 另一个是挖坑的初始化
  • 通过Excel学习PID算法(一步步理解它的KP,KI,KD)

    PID原理 PID控制算是应用非常广泛的经典控制算法 但是怎么理解PID这三个参数呢 xff1f 在参考了别人的文章之后 xff0c 我还是有点一知半解 xff0c 这时候发现不自己动手算一算是很难理解PID了 xff0c 但是我又不想做这
  • 通过Excel学习PID算法(连续系统的PID)

    总结上一节 在之前 xff0c 我们用倒水的例子通俗易懂的解释了什么是PID算法 在这里先回顾一下之前的学习的内容 P表示对误差的比例系数 与目标值差多少 xff0c 就在下一次修正中加上这个误差与P的乘积 xff0c 同时会导致系统有一个
  • 原来学习是如此地苦涩

    原文链接 xff1a http blog csdn net tangl 99 article details 2047657 最近一直在忙第一篇Paper xff0c 虽然想法大致的框架成熟了 xff0c 但是还有一些细节需要完善 这几天在
  • 互联网+时代的7个引爆点(读书笔记)

    百货商场里的销售人员一直抱怨 xff0c 大家只是到自己这里来看看 xff0c 之后转身就在网上下单 从旧视角瞎看这固然是一种文体 xff0c 显示着揭示了一种新的机会 以线下体验为入口的机会 小团队精益式的迭代 xff0c 几个周期后就可
  • maperuce运算框架

    1 xff0c 概念 mapreduce 运算框架主要实现hadoop 的数据处理 xff0c 数据处理中 流经过5个节点 数据流 xff1a input gt spilt gt map gt shuffle gt reduce xff08
  • 在Python中使用print输出时,出现UnicodeEncodeError错误,错误提示为“‘gbk‘ codec can‘t encode character ‘\u2022‘ in posit

    利用chatgpt一步步解决了这个问题 xff0c 感觉ChatGPT还是太强大了 问题描述 xff1a 在Python中使用print输出时 xff0c 出现UnicodeEncodeError错误 xff0c 错误提示为 39 gbk
  • openstack一些特性资料

    Keystone RBAC nova compute Cells Bare Metal Compute 是什么东西 xff1f http wiki openstack org blueprint nova compute cells htt
  • 【神经网络和深度学习-开发案例】 第二章 神经网络结构

    神经网络和深度学习 第二章 神经网络结构 案例 xff1a 使用神经网络识别手写数字 我将介绍一个神经网络 xff0c 它可以很好地对手写的数字进行分类 为了准备这一点 xff0c 它有助于解释一些术语 xff0c 让我们可以命名一个网络的
  • 2000页kubernetes操作手册,内容详细代码清晰,小白也能看懂

    现如今 xff0c Kubernetes业务已成长为新时代的IT基础设施 xff0c 并成为高级运维工程师 架构师 后端开发工程师的必修技术栈 毫无疑问 xff0c Kubernetes是云计算发展演进的一次彻底革命性的突破 xff0c 只
  • FreeRTOS代码阅读笔记:heap_4.c

    FreeRTOS中对于内存的管理当前一共有5种实现方式 xff08 作者当前的版本是10 1 1 xff09 xff0c 均在 Source portable MemMang 下面 xff0c 这里笔记下 heap 4 c和第二种方式比较相
  • (1)touchgfx 添加时钟控件

    第一步 xff1a 新建空白模版 添加图片 xff1a 放入 链接 xff1a https pan baidu com s 1NI6LUYrTUs64Z2jZE6AAQQ 提取码 xff1a 2odw 添加控件 xff1a 位置部件属性1T
  • 【基于51】红外寻迹智能小车 - 代码篇

    文章目录 前言一 准备工作二 使用步骤1 模块化编程2 电机模块3 小车动作模块4 PWM 和定时器 中断系统5 寻迹逻辑 总结 前言 关于硬件部分可以看我上次写的帖子https blog csdn net ZER00000001 arti
  • C++关键字override

    一 什么是override override的翻译是覆盖 实际上它在C 43 43 中可以检测哪些虚函数没有被重写并报错 注 xff1a 在派生类的成员函数中使用override时 xff0c 如果基类中无此函数 xff0c 或基类中的函数
  • 邻接矩阵和邻接表

    图的概述和存储结构 xff08 一 xff09 文章目录 前言一 图的概述1 xff09 图的分类2 xff09 图的要素 二 图的存储结构三 邻接矩阵四 邻接表 前言 有一种说法是程序是由数据结构和算法组成的 xff0c 这很能体现出数据