【数据结构与算法】图的概述(内含源码)

news2024/9/25 21:23:31

个人主页:【😊个人主页】
系列专栏:【❤️数据结构与算法】
学习名言:天子重英豪,文章教儿曹。万般皆下品,惟有读书高——《神童诗劝学》


在这里插入图片描述


系列文章目录

第一章 ❤️ 学前知识
第二章 ❤️ 单向链表
第三章 ❤️ 递归


文章目录

  • 系列文章目录
  • 前言
  • 什么是图?
  • 图的分类
    • 图按照无方向和有方向分为:无向图和有向图。
    • 图按照边分为:稀疏图和稠密图
    • 完全图
  • 顶点与边
    • 顶点与边的关系
  • 图的存储结构
    • 邻接列表
    • 邻接矩阵
  • 图的定义和术语总结


前言

与线性表中的元素是“一对一”的关系和树中的元素是“一对多”的关系不同的是,数据结构中图的元素则是“多对多”的关系。图(Graph)是一种复杂的非线性结构,在图结构中,每个元素都可以有零个或多个前驱,也可以有零个或多个后继,也就是说,元素之间的关系是任意的,今天就让我来带大家了解数据结构中图结构吧。


什么是图?

在计算机科学中,一个图就是一些顶点的集合,这些顶点通过一系列边结对(连接)。顶点用圆圈表示,边就是这些圆圈之间的连线。顶点之间通过边连接。
顶点有时也称为节点或者交点,边有时也称为链接
图有各种形状和大小。边可以有权重(weight),即每一条边会被分配一个正数或者负数值。

图(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G中边的集合

在这里插入图片描述


图的分类

图按照无方向和有方向分为:无向图和有向图。

在这里插入图片描述

不带有箭头指向的图只由顶点和边构成称为无向图,有向图是由顶点和弧(有向边构成)。弧有弧头和弧尾区别。

图按照边分为:稀疏图和稠密图

这是个模糊的概念,同样是相对的概念。

完全图

如果任意两个顶点之间都存在边叫完全图,有向的边叫有向完全图。如果无重复的边或者顶点到自身的边叫简单图。在用数学方式表示时,无向边用()表示,有向边用<>表示。我们目前接触到的图全是简单图。

在这里插入图片描述没有重复的边或者到自身的边(简单图),右图则有

在这里插入图片描述这种边带权值的图叫网


顶点与边

顶点与边的关系

  • 顶点的度:顶点关联边的数目。有向图图中有,入度:方向指向顶点的边;出度:方向背向顶点的边。在有向图中顶点的度就是两者之和。
  • 路径长度:路径上边或者弧的数目。

图的存储结构

理论上,图就是一堆顶点和边对象而已,那我们又如何用代码来实现它呢?

通常我们有两种选择:邻接列表和邻接矩阵。

邻接列表

邻接表,存储方法跟树的孩子链表示法相类似,是一种顺序分配和链式分配相结合的存储结构。如这个表头结点所对应的顶点存在相邻顶点,则把相邻顶点依次存放于表头结点所指向的单向链表中。
对于无向图来说,使用邻接表进行存储也会出现数据冗余,表头结点A所指链表中存在一个指向C的表结点的同时,表头结点C所指链表也会存在一个指向A的表结点。

在这里插入图片描述
顶点表的各个结点由data(数据域)和Firstedge(指针域)两个域表示,data是数据域,指针域指向边表的第一个结点,即顶点的第一个邻接点。边表结点由adjvex(邻接点域)和next两个域组成。
邻接点域存储某顶点的邻接点在顶点表中坐标,next存储边表中下一个结点指针。
如图中v1顶点与v2、v0互为邻接点,则在v1边表中,adjvex分别为0和2。
有向图也可以用邻接表,出度表叫邻接表,入度表尾逆邻接表

#include <stdio.h>
#include <stdlib.h>

// 邻接表中每个节点的结构体
struct AdjListNode {
    int dest;
    struct AdjListNode* next;
};

// 邻接表的结构体
struct AdjList {
    struct AdjListNode *head;
};

// 图的结构体
struct Graph {
    int V;
    struct AdjList* array;
};

// 创建一个新的邻接表节点
struct AdjListNode* newAdjListNode(int dest) {
    struct AdjListNode* newNode = (struct AdjListNode*)malloc(sizeof(struct AdjListNode));
    newNode->dest = dest;
    newNode->next = NULL;
    return newNode;
}

// 创建一个具有V个顶点的新图
struct Graph* createGraph(int V) {
    struct Graph* graph = (struct Graph*)malloc(sizeof(struct Graph));
    graph->V = V;

    // 创建邻接表数组
    graph->array = (struct AdjList*)malloc(V * sizeof(struct AdjList));

    // 初始化链表头为空
    for (int i = 0; i < V; ++i)
        graph->array[i].head = NULL;

    return graph;
}

// 添加一个边到无向图
void addEdge(struct Graph* graph, int src, int dest) {
    // 添加一条从src到dest的边
    struct AdjListNode* newNode = newAdjListNode(dest);
    newNode->next = graph->array[src].head;
    graph->array[src].head = newNode;

    // 添加一条从dest到src的边,因为是无向图
    newNode = newAdjListNode(src);
    newNode->next = graph->array[dest].head;
    graph->array[dest].head = newNode;
}

// 打印邻接列表表示的图
void printGraph(struct Graph* graph) {
    for (int v = 0; v < graph->V; ++v) {
        struct AdjListNode* pCrawl = graph->array[v].head;
        printf("\n 邻接列表%d: ", v);
        while (pCrawl) {
            printf("-> %d", pCrawl->dest);
            pCrawl = pCrawl->next;
        }
        printf("\n");
    }
}

int main() {
    // 创建一个具有5个顶点的新图
    struct Graph* graph = createGraph(5);

    // 添加边
    addEdge(graph, 0, 1);
    addEdge(graph, 0, 2);
    addEdge(graph, 1, 2);
    addEdge(graph, 1, 3);
    addEdge(graph, 2, 3);
    addEdge(graph, 2, 4);
    addEdge(graph, 3, 4);

    // 打印邻接列表表示的图
    printGraph(graph);

    return 0;
}

邻接矩阵

邻接矩阵(Adjacency Matrix):是表示顶点之间相邻关系的矩阵。设G=(V,E)是一个图,其中V={v1,v2,…,vn}。G的邻接矩阵是一个具有下列性质的n阶方阵:
在这里插入图片描述

  • 对无向图而言,邻接矩阵一定是对称的,而且主对角线一定为零(在此仅讨论无向简单图),副对角线不一定为0,有向图则不一定如此。
  • 在无向图中,任一顶点i的度为第i列(或第i行)所有非零元素的个数,在有向图中顶点i的出度为第i行所有非零元素的个数,而入度为第i列所有非零元素的个数。
  • 用邻接矩阵法表示图共需要n^2个空间,由于无向图的邻接矩阵一定具有对称关系,所以扣除对角线为零外,仅需要存储上三角形或下三角形的数据即可,因此仅需要n(n-1)/2个空间
#include <stdio.h>

#define MAX_NODES 100

int adj_matrix[MAX_NODES][MAX_NODES];

void add_edge(int start, int end) {
    adj_matrix[start][end] = 1;
    adj_matrix[end][start] = 1; // 无向图需要将两个方向都标记为已连接
}

int main() {

    // 添加边
    add_edge(0, 1);
    add_edge(0, 2);
    add_edge(1, 2);
    add_edge(2, 3);

    // 输出邻接矩阵
    printf("邻接矩阵:\n");
    for (int i = 0; i < MAX_NODES; i++) {
        for (int j = 0; j < MAX_NODES; j++) {
            printf("%d ", adj_matrix[i][j]);
        }
        printf("\n");
    }

    return 0;
}

图的定义和术语总结

顶点(Vertex):图中的数据元素通常称为顶点
弧(Arc):若< v,w >∈VR,则< v,w >表示从v到w的一条弧
弧尾(Tail):v为弧尾或初始点(Initial node)
弧头(Head):w为弧头或终端点(Terminal node)
有向图(Digraph):图中每条边都有方向
无向图(Undigraph):图中每条边都没有方向
连通图(Connected Graph):对于图中任意两个顶点v,j∈V,v和j都是连通的,则称G是连通图
连通分量(Connected Compenent):无向图中的极大连通子图
完全图(Completed graph):有1/2*n(n-1)条边的无向图称为完全图
有向完全图:具有n(n-1)条弧的有向图称为有向完全图
稀疏图(Sparse graph):有很少条边或弧(如e < nlogn)的图称为稀疏图
稠密图(Dense graph):有很多条边或弧
权(Weight):有时图的边或弧具有与它相关的数,这种与图的边或弧相关的数叫做权
度(Degree):定点v的度是和v相关联的边的数目,记为TD(V)
入度(InDegree):以顶点v为头的弧的数目称为v的入度,记为ID(v)
出度(Outdegree):以v为尾的弧的数目成为v的出度,记为OD(v)
V: 是顶点的有穷非空集合
VR:是两个顶点之间的关系的集合
n:表示图中顶点数目
e:表示边或弧的数目

在这里插入图片描述

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

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

相关文章

分布式一致性Hash算法原理及实现

文章目录 一致性Hash原理提高容错性和和扩展性一致性Hash实现思路代码 一致性Hash原理 简单来说&#xff0c;一致性Hash算法将整个哈希值空间组织成一个虚拟的圆环&#xff0c; 如假设某哈希函数 H 的值空间为 0 ~ 2^32-1&#xff08;即哈希值是一个32位无符号整形&#xff09;…

搜狗百科怎么创建?搜狗百科创建指南(经验分享)

搜狗百科是一个允许用户创建、编辑和维护百科全书的网站。它是搜狗搜索旗下的一个产品&#xff0c;为用户提供了一个共享知识的平台。创建一个搜狗百科词条并非难事&#xff0c;但需要遵守一些注意事项。 话不多说。小媒同学将介绍搜狗百科词条的创建过程和注意事项。 一、创建…

java基础入门-04-【集合学生管理系统】

Java基础入门-04-【集合&学生管理系统】 11、集合&学生管理系统11.1.ArrayList集合和数组的优势对比&#xff1a;11.1.1 ArrayList类概述11.1.2 ArrayList类常用方法11.1.2.1 构造方法11.1.2.2 成员方法11.1.2.3 示例代码 11.1.3 ArrayList存储字符串并遍历11.1.3.1 案…

【观察】甲骨文以“双引擎”驱动,加速中国企业拥抱决策智能

毫无疑问&#xff0c;当前中国整体经济形态正在从传统经济向数字经济转型&#xff0c;千行百业也在加速数字化转型&#xff0c;特别是随着企业数据的沉淀越来越庞大&#xff0c;对数据平台以及智能决策等新技术的需求也越来越旺盛。 国家发布的《“十四五”数字经济发展规划》中…

视频里的音乐怎么转换成mp3格式?

视频里的音乐怎么转换成mp3格式&#xff1f;视频里的音乐转换为mp3的原因有很多&#xff0c;主要是因为mp3格式是一种音频格式&#xff0c;文件大小较小&#xff0c;更易于存储和传输。相比之下&#xff0c;视频格式则是一种视频文件格式&#xff0c;虽然包含音频&#xff0c;但…

Q-in-Q 和 MAC-in-MAC

例题引入&#xff1a; 1. 城域以太网在各个用户以太网之间建立多点第二层连接&#xff0c;IEEE802.1ad定义运营商网桥协议提供的基本技术是在以太网帧中插入&#xff08;26&#xff09;字段&#xff0c;这种技术被称为&#xff08;27&#xff09;技术。 (26)A.运营商VLAN标记…

Hive知识点的回顾

一、Hive的序列化和反序列化 Hive读取文件机制&#xff1a;读取文件中的每一行 > 反序列化 > 通过分隔符进行切割&#xff0c;返回数据表中的每一行对象。 Hive写文件机制&#xff1a;把数据表中的每一行Row对象 > 调用LazySimpleSerde类中的序列化方法 > 把Row对象…

基于AT89C51单片机的电子秒表设计与仿真

点击链接获取Keil源码与Project Backups仿真图&#xff1a; https://download.csdn.net/download/qq_64505944/87759735?spm1001.2014.3001.5503 源码获取 主要内容&#xff1a; 设计一个电子钟,实现对时、分、秒的显示的控制,电路采用24小时计时方式。另一个功能是秒表功能…

JVM内存模型和结构介绍

什么是JVM JVM是Java Virtual Machine&#xff08;Java虚拟机&#xff09;的缩写&#xff0c;JVM是一个虚构出来的计算机&#xff0c;有着自己完善的硬件架构&#xff0c;如处理器、堆栈等。 为什么需要JVM&#xff1f; Java语言使用Java虚拟机屏蔽了与具体平台相关的信息&…

执行网格中有特定数量节点的传感器网络部署(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 ​无线传感器网络是通过大量分布的传感器节点作为终端来协同感知和自主地监测外部世界,以多跳、自组织或协作的方式进行通信和…

Java 基础进阶篇(十二)—— Arrays 与 Collections 工具类

文章目录 一、Arrays工具类1.1 Arrays 类常用方法1.2 对于 Comparator 比较器的支持1.3 Arrays 的综合应用1.3.1 应用一&#xff1a;数组的降序排序1.3.2 应用二&#xff1a;根据学生年龄进行排序 二、Collections工具类2.1 Collections 类常用方法2.2 Collections 排序相关 AP…

哈希表相关知识总结

一、哈希表的定义 散列表&#xff08;Hash table&#xff0c;也叫哈希表&#xff09;&#xff0c;是根据键&#xff08;Key&#xff09;而直接访问在内存存储位置的数据结构。也就是说&#xff0c;它通过计算一个关于键值的函数&#xff0c;将所需查询的数据映射到表中一个位置…

C++相比于C语言增加的8个特性(详解)

C相比于C语言增加的8个特性&#xff08;详解&#xff09; 文章目录 C相比于C语言增加的8个特性&#xff08;详解&#xff09;一、命名空间二、C输入和输出三、缺省参数四、函数重载五、引用六、内联函数七、auto关键字八、指针空值nullptr总结 一、命名空间 c的命名空间是为了…

【刷题之路】LeetCode 21. 合并两个有序链表

【刷题之路】LeetCode 21. 合并两个有序链表 1、题目描述二、解题1、方法1——直接合并1.1、思路分析1.2、代码实现 2、方法2——递归2.1、思路分析2.2、代码实现 1、题目描述 原题连接&#xff1a; 21. 合并两个有序链表 题目描述&#xff1a; 将两个升序链表合并为一个新的 …

Camtasia Studio2023Mac最新电脑版屏幕录像软件

Camtasia Studio2023提供了强大的屏幕录像、视频的剪辑和编辑、视频菜单制作、视频剧场和视频播放功能等。它能在任何颜色模式下轻松地记录屏幕动作&#xff0c;包括影像、音效、鼠标移动的轨迹&#xff0c;解说声音等等&#xff0c;另外&#xff0c;它还具有及时播放和编辑压缩…

数字化转型导师坚鹏:美的集团数字化转型案例研究

美的集团数字化转型案例研究 课程背景&#xff1a; 很多企业存在以下问题&#xff1a; 不清楚企业数字化转型能否成功&#xff1f; 不知道其它企业数字化转型的实际做法&#xff1f; 不知道其它企业的数字化转型战略是如何演变的&#xff1f; 课程特色&#xff1a; 用…

汽车架构-工作流程 以及相关协议解读

全车架构&#xff08;E/E&#xff09; 车载测试阶段&#xff1a; 台架测试 HIL测试&#xff08;硬件在环测试&#xff09; ADAS智能辅助驾驶测试 OTA测试&#xff08;远程升级测试&#xff09; 测试工具&#xff1a; Can协议工具&#xff1a;Canoe Pcan Zcanpro 辅助工具…

【Stable Diffusion】ControlNet基本教程(三)

接上篇【Stable Diffusion】ControlNet基本教程&#xff08;二&#xff09;&#xff0c;本篇再介绍两个ControlNet常见的基本用法&#xff0c;更多用法欢迎关注博主&#xff0c;博主还会更新更多有趣的内容。 3.3更换物体皮肤 有时&#xff0c;我们不想改变物体的轮廓&#xff…

毫米波雷达系列 | 传统CFAR检测(均值类)

毫米波雷达系列 | 传统CFAR检测&#xff08;均值类&#xff09; 文章目录 毫米波雷达系列 | 传统CFAR检测&#xff08;均值类&#xff09;1.CA-CFAR算法2.SO-CFRA算法3.GO-CFAR算法4.仿真对比 CFAR检测器主要用于检测背景杂波环境中的雷达目标&#xff0c;常见的均值类CFAR检测…

数据结构之队列的详解

文章目录 一.什么是队列二.队列的使用2.1 队列的基本操作2.2 队列的基本使用 三.队列的模拟实现3.1 数组实现队列3.2 链表实现队列 四.队列的应用4.1 设计循环队列4.2 设计双端队列4.3 队列实现栈4.4 栈实现队列 五.总结 一.什么是队列 队列是一种先入先出(FIFO)的线性表数据结…