【数据结构】图的存储结构

图是一种非常重要的数据结构,用于描述各种复杂的关系和网络。在计算机科学中,图的存储结构对于图算法的设计和实现至关重要。本文将深入探讨图的两种常见存储结构——邻接矩阵和邻接表,并提供C语言代码示例,演示如何在程序中实现这两种存储结构,并讨论它们的优缺点以及适用场景。

1. 邻接矩阵(Adjacency Matrix)

邻接矩阵是一种二维数组,用于表示图中节点和边的关系。如果图中的顶点数量为 n,则邻接矩阵的大小为 n × n。矩阵中的每个元素表示两个顶点之间是否存在边,通常用 0 或 1 表示。

优点:

  • 直观简单:邻接矩阵直观地表示了图的连接关系,易于理解和实现。
  • 方便查找:可以快速查找任意两个顶点之间是否存在边,时间复杂度为 O(1)。

缺点:

  • 空间复杂度高:对于稀疏图(边数远小于顶点数),邻接矩阵会浪费大量空间。
  • 添加和删除顶点困难:当需要添加或删除顶点时,需要重新分配内存并复制数据,效率较低。

2. 邻接表(Adjacency List)

邻接表是一种链表数组,用于表示图中节点和边的关系。每个顶点都有一个链表,存储与其相连的所有顶点。

优点:

  • 空间效率高:对于稀疏图,邻接表可以节省大量空间,只存储实际存在的边。
  • 添加和删除顶点方便:添加或删除顶点时,只需修改相应链表,效率较高。

缺点:

  • 查找边的效率较低:查找任意两个顶点之间是否存在边的时间复杂度为 O(V),其中 V 是顶点数。
  • 不直观:相比邻接矩阵,邻接表的结构相对复杂,不够直观。

下面分别通过C语言代码示例,演示如何在程序中实现邻接矩阵和邻接表,并讨论它们的适用场景:

// 邻接矩阵示例
#include <stdio.h>
#include <stdlib.h>

#define MAX_VERTICES 100

typedef struct {
    int numVertices;
    int matrix[MAX_VERTICES][MAX_VERTICES];
} Graph;

Graph* createGraph(int numVertices) {
    Graph* graph = (Graph*)malloc(sizeof(Graph));
    graph->numVertices = numVertices;
    for (int i = 0; i < numVertices; i++) {
        for (int j = 0; j < numVertices; j++) {
            graph->matrix[i][j] = 0;
        }
    }
    return graph;
}

void addEdge(Graph* graph, int src, int dest) {
    graph->matrix[src][dest] = 1;
    // 对于无向图,还需设置 matrix[dest][src] = 1;
}

void printGraph(Graph* graph) {
    printf("图的邻接矩阵表示:\n");
    for (int i = 0; i < graph->numVertices; i++) {
        for (int j = 0; j < graph->numVertices; j++) {
            printf("%d ", graph->matrix[i][j]);
        }
        printf("\n");
    }
}

// 邻接表示例
#include <stdio.h>
#include <stdlib.h>

#define MAX_VERTICES 100

typedef struct Node {
    int vertex;
    struct Node* next;
}

 Node;

typedef struct {
    int numVertices;
    Node* adjList[MAX_VERTICES];
} Graph;

Graph* createGraph(int numVertices) {
    Graph* graph = (Graph*)malloc(sizeof(Graph));
    graph->numVertices = numVertices;
    for (int i = 0; i < numVertices; i++) {
        graph->adjList[i] = NULL;
    }
    return graph;
}

void addEdge(Graph* graph, int src, int dest) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->vertex = dest;
    newNode->next = graph->adjList[src];
    graph->adjList[src] = newNode;

    // 对于无向图,还需反向添加边
    newNode = (Node*)malloc(sizeof(Node));
    newNode->vertex = src;
    newNode->next = graph->adjList[dest];
    graph->adjList[dest] = newNode;
}

void printGraph(Graph* graph) {
    printf("图的邻接表表示:\n");
    for (int i = 0; i < graph->numVertices; i++) {
        Node* temp = graph->adjList[i];
        printf("顶点 %d 的邻接表:", i);
        while (temp) {
            printf(" -> %d", temp->vertex);
            temp = temp->next;
        }
        printf("\n");
    }
}

int main() {
    // 邻接矩阵示例
    Graph* graph1 = createGraph(5);
    addEdge(graph1, 0, 1);
    addEdge(graph1, 0, 2);
    addEdge(graph1, 1, 2);
    addEdge(graph1, 1, 3);
    addEdge(graph1, 2, 3);
    addEdge(graph1, 3, 4);
    printGraph(graph1);

    // 邻接表示例
    Graph* graph2 = createGraph(5);
    addEdge(graph2, 0, 1);
    addEdge(graph2, 0, 2);
    addEdge(graph2, 1, 2);
    addEdge(graph2, 1, 3);
    addEdge(graph2, 2, 3);
    addEdge(graph2, 3, 4);
    printGraph(graph2);

    return 0;
}

通过以上代码示例和讨论,我们深入了解了图的两种常见存储结构——邻接矩阵和邻接表,以及它们的优缺点和适用场景。在实际应用中,需要根据具体情况选择合适的存储结构,以实现更高效的图算法和应用。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【QT】ROS2 Humble联合使用QT教程

【QT】ROS2 Humble联合使用QT教程 文章目录 【QT】ROS2 Humble联合使用QT教程1. 安装ROSProjectManager插件2. 创建ROS项目3.一个快速体验的demoReference 环境的具体信息如下&#xff1a; ubunt 22.04ros2 humbleQt Creator 13.0.0ROS ProjectManager 13.0.0 本文建立在已经…

Vivado-IP-DDS and Testbench Learning

DDS内部结构 实现流程 首先新建一个工程&#xff0c;创建bd文件&#xff0c;添加DDS Compiler核&#xff0c;此处不多赘述 Block Design 在观测输出的信号时&#xff0c;需要将最高位符号位的信号取反&#xff0c;这样才能输出正弦波&#xff0c;否则输出的波形如下图所示 将t…

OpenStack云计算(十)——OpenStack虚拟机实例管理,增加一个计算节点并进行实例冷迁移,增加一个计算节点的步骤,实例冷迁移的操作方法

项目实训一 本实训任务对实验环境要求较高&#xff0c;而且过程比较复杂&#xff0c;涉及的步骤非常多&#xff0c;有一定难度&#xff0c;可根据需要选做。可以考虑改为直接观看相关的微课视频 【实训题目】 增加一个计算节点并进行实例冷迁移 【实训目的】 熟悉增加一个…

实验 1--SQL Server2008数据库开发环境

文章目录 实验 1--SQL Server2008数据库开发环境2.4.1 实验目的2.4.2 实验准备2.4.3 实验内容1.利用 SSMS 访问系统自带的Report Server 数据库。2.熟悉了解 SMSS对象资源管理器树形菜单相关选择项的功能。(1)右键单击数据库Report Server&#xff0c;查看并使用相关功能;(2)选…

K8s: 部署 kubernetes dashboard

部署 Dashboard K8s 官方有一个项目叫 dashboard&#xff0c;通过这个项目更方便监控集群的状态 官方地址: https://github.com/kubernetes/dashboard 通常我们通过命令行 $ kubectl get po -n kube-system 能够查看到集群所有的组件&#xff0c;但这样的方式比较不太直观 …

算法学习002-填数游戏 中小学算法思维学习 信奥算法解析 c++实现

目录 C填数游戏 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、推荐资料 C填数游戏 一、题目要求 1、编程实现 在小学奥数中经常会看到一些填数字的游戏&#xff0c;如下图所示&#xff0c;其中每个…

【Web】第三次

【Web】第三次 1.完成学校官方网站页面制作2.使用动画完成过渡变换效果 1.完成学校官方网站页面制作 2.使用动画完成过渡变换效果 1.完成学校官方网站页面制作 html&#xff1a; <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://…

OpenCV 实现重新映射

返回:OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;OpenCV 实现霍夫圆变换 下一篇 :OpenCV实现仿射变换 目标 在本教程中&#xff0c;您将学习如何&#xff1a; 一个。使用 OpenCV 函数 cv&#xff1a;&#xff1a;remap 实现简单的重新…

Socket编程实验

文章目录 服务端&#xff1a;客户端&#xff1a;使用说明&#xff1a;封装后服务端&#xff1a;封装后客户端 听学弟学妹们反馈&#xff0c;好像老师发的socket编程实验指导里的代码跑不起来。 今天花了一大把时间写了下socket编程代码 现在附上能跑的c代码&#xff1a; 最重要…

nosql数据库 redis

一、介绍 1、redis与mysql的区别&#xff1a; Redis是一种基于键值对的内存数据库&#xff0c;数据存储在内存中&#xff0c;因此读写速度非常快。它支持多种数据结构&#xff0c;如字符串、哈希、列表等。 MySQL是一种关系型数据库&#xff0c;数据以表格的形式组织存储在磁…

12.6.1 实验5:IOS恢复

1、实验目的 通过本实验可以掌握&#xff1a; copy方式恢复IOS的步骤。TFTPDNLD方式恢复IOS的步骤。Xmodem方式恢复IOS的步骤。 2、实验拓扑 路由器IOS恢复的实验拓扑如下图所示。 3、实验步骤 如果工作中不慎误删除路由器IOS&#xff0c;或者升级了错误版本的IOS&#xff…

Sylar C++高性能服务器学习记录06 【线程模块-代码分析篇】

早在19年5月就在某站上看到sylar的视频了&#xff0c;一直认为这是一个非常不错的视频&#xff0c;还有幸加了sylar本人的wx&#xff0c;由于本人一直是自学编程&#xff0c;基础不扎实&#xff0c;也没有任何人的督促&#xff0c;没能坚持下去&#xff0c;每每想起倍感惋惜。恰…

机器学习day3

一、距离度量 1.欧氏距离 2.曼哈顿距离 3.切比雪夫距离 4.闵可夫斯基距离 二、特征与处理 1.数据归一化 数据归一化是一种将数据按比例缩放&#xff0c;使之落入一个小的特定区间的过程。 代码实战 运行结果 2.数据标准化 数据标准化是将数据按照其均值和标准差进行缩放的过…

2024最新版JavaScript逆向爬虫教程-------基础篇之面向对象

目录 一、概念二、对象的创建和操作2.1 JavaScript创建对象的方式2.2 对象属性操作的控制2.3 理解JavaScript创建对象2.3.1 工厂模式2.3.2 构造函数2.3.3 原型构造函数 三、继承3.1 通过原型链实现继承3.2 借用构造函数实现继承3.3 寄生组合式继承3.3.1 对象的原型式继承3.3.2 …

paddle ocr v4 微调训练文字识别模型实践

识别步骤参考&#xff1a;https://github.com/PaddlePaddle/PaddleOCR/blob/main/doc/doc_ch/recognition.md 微调步骤参考:https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.7.1/doc/doc_ch/finetune.md 训练必要性 原始模型标点符号和括号容易识别不到 数据准备…

【漏洞复现】Weblogic 任意文件上传漏洞(CVE-2018-2894)

漏洞简介 Oracle在7月更新中&#xff0c;修复了Weblogic Web Service Test Page中一处任意文件上传漏洞&#xff0c;Web Service Test Page在"生产模式"下默认不开启&#xff0c;所以该漏洞有一定限制&#xff0c;利用该漏洞&#xff0c;可以上传任意.jsp文件&#x…

用Redis实现获取验证码,外加安全策略

安全策略 一小时内只能获取三次&#xff0c;一天内只能获取五次 Redis存储结构 代码展示 import cn.hutool.core.util.RandomUtil; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.junit.jupiter.api.Test; import org.spri…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-6

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

RK3588 - RKNN(Rockchip 神经处理单元)的逆向工程

本文翻译自https://jas-hacks.blogspot.com/2024/02/rk3588-reverse-engineering-rknn.html RK3588 NPU 的内部操作和功能主要隐藏在名为RKNPU2的闭源 SDK 中。由于对大型语言模型 (LLM) 的兴趣以及对transform模型最佳矩阵乘法的追求&#xff0c;想了解 RKNPU SDK 新引入的矩阵…

值得让英伟达CEO黄仁勋亲自给OpenAI配送的AI服务器!一文带你了解算力,GPU,CPU!

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;所以创建了“AI信息Gap”这个公众号&#xff0c;专注于分享AI全维度知识…
最新文章