数据结构--图

news2024/11/25 20:15:39

  树具有灵活性,并且存在许多不同的树的应用,但是就树本身而言有一定的局限性,树只能表示层次关系,比如父子关系。而其他的比如兄弟关系只能够间接表示。

推广---  图

图形结构中,数据元素之间的关系是任意的。

一、图的基本概念

二、图的分类

三、图的相关术语

1、顶点的度

无向图:n个顶点找两条,没有方向,

2、路径和路径长度

3.子图

4.图的连通

1)无向图的连通

2)有向图的连通

5.生成树

#不讨论的图:

四、图的存储方法

1、邻接矩阵存储方法

对称矩阵:

一个对称矩阵是指矩阵的主对角线两侧的元素相等。在这个矩阵中,通过观察可以发现对称性质:矩阵的第i行第j列的元素等于第j行第i列的元素。

**无向图的邻接矩阵建图和度数输出(完整代码)

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#define N (100 + 5)
#define INF 0x3f3f3f3f//定义INF为一个十六进制无穷大常量

typedef char VexType; //顶点为字符类型
typedef int EdgeType;//邻接矩阵类型为整型

typedef struct {
    int n, m; //n个顶点,m条边
    VexType vex[N];//一维数组存放所有顶点的数据信息
    EdgeType edge[N][N];//邻接矩阵(二维数组存放图中所有顶点之间关系的信息)
} adjGraph;

//1.邻接矩阵建图
adjGraph createGraph();
//2.输出图的信息(顶点、邻接矩阵)
void print(adjGraph g);
//3.输出图中每个顶点的度数
void printDegree(adjGraph g);

int main()
{
    //1.建图
    adjGraph g = createGraph();
    //2.输出图的信息
    print(g);
    printDegree(g);
    return 0;
}

adjGraph createGraph()//建图
{
    adjGraph g;
    memset(g.edge, 0, sizeof(g.edge));//内存设置函数--创建图的过程中,所有元素初始化为0
    // g.edge 邻接矩阵
    //sizeof(g.edge) 数组占用的总字节数
    scanf("%d%d", &g.n, &g.m);//输入顶点数和边数
    getchar();//吸收换行符
    //1.输入n个顶点
    for (int i = 0; i < g.n; i++) {
        scanf("%c ", &g.vex[i]);
    }
    //2.输入m条边,按照邻接矩阵存图
    for (int i = 0; i < g.m; i++) {
        char v1, v2;
        scanf("\n%c %c", &v1, &v2);//读入当前边的2个顶点
        int n1 = v1 - 'A', n2 = v2 - 'A';
         //将顶点字符转换为对应的数组索引。
        // 假设顶点标签是大写字母'A'、'B'、'C'等,通过将其减去字符'A'的ASCII码值
        // 可以得到对应的数组索引(0、1、2等)。   
        g.edge[n1][n2] = g.edge[n2][n1] = 1;
        //无向图,邻接矩阵对应的n1行n2列和n2n1列都赋值为1(邻接矩阵的对称性)
        //将对应的邻接矩阵元素设置为1,表示图中对应的顶点之间存在一条边。
    }

    return g;
}

void print(adjGraph g)
{
    printf("图有%d个顶点,%d条边\n", g.n, g.m);
    printf("图的顶点是:");
    for (int i = 0; i < g.n; i++) {
        printf("%c ", g.vex[i]);
    }
    printf("\n图的邻接矩阵是:\n");
    for (int i = 0; i < g.n; i++) {
        for (int j = 0; j < g.n; j++) {
            printf("%4d", g.edge[i][j]);
        }
        printf("\n");
    }
}

void printDegree(adjGraph g)
{
    printf("图中每个顶点的度数是:");
    for (int i = 0; i < g.n; i++) {
        int degree = 0;
        for (int j = 0; j < g.n; j++) {
            if (g.edge[i][j] == 1) {
                degree++;
            }
        }
        printf("%c: %d ", g.vex[i], degree);
    }
    printf("\n");
}

输入样例:

**有向图邻接矩阵建图和度数输出(附完整代码)

修改的部分:

  • 将g.edge[n1][n2] = g.edge[n2][n1] = 1; 修改为 g.edge[n1][n2] = 1; 表示从顶点n1指向顶点n2的有向边。
  • 把无向图中的度数输出改成入度和出度输出
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#define N (100 + 5)
#define INF 0x3f3f3f3f//定义INF为一个十六进制无穷大常量

typedef char VexType; //顶点为字符类型
typedef int EdgeType;//邻接矩阵类型为整型

typedef struct {
    int n, m; //n个顶点,m条边
    VexType vex[N];//一维数组存放所有顶点的数据信息
    EdgeType edge[N][N];//邻接矩阵(二维数组存放图中所有顶点之间关系的信息)
} adjGraph;

//1.邻接矩阵建图
adjGraph createGraph();
//2.输出图的信息(顶点、邻接矩阵)
void print(adjGraph g);
//3.输出图中每个顶点的度数
void printDegree(adjGraph g);

int main()
{
    //1.建图
    adjGraph g = createGraph();
    //2.输出图的信息
    print(g);
    printDegree(g);
    return 0;
}

adjGraph createGraph()//建图
{
    adjGraph g;
    memset(g.edge, 0, sizeof(g.edge));//内存设置函数--创建图的过程中,所有元素初始化为0
    // g.edge 邻接矩阵
    //sizeof(g.edge) 数组占用的总字节数
    scanf("%d%d", &g.n, &g.m);//输入顶点数和边数
    getchar();//吸收换行符
    //1.输入n个顶点
    for (int i = 0; i < g.n; i++) {
        scanf("%c ", &g.vex[i]);
    }
    //2.输入m条边,按照邻接矩阵存图
    for (int i = 0; i < g.m; i++) {
        char v1, v2;
        scanf("\n%c %c", &v1, &v2);//读入当前边的2个顶点
        int n1 = v1 - 'A', n2 = v2 - 'A';
        //将顶点字符转换为对应的数组索引。
       // 假设顶点标签是大写字母'A'、'B'、'C'等,通过将其减去字符'A'的ASCII码值
       // 可以得到对应的数组索引(0、1、2等)。   
        g.edge[n1][n2] = 1;
        //有向图,邻接矩阵对应的n1行n2列赋值为1
        //将对应的邻接矩阵元素设置为1,表示图中对应的顶点之间存在一条边。
    }

    return g;
}

void print(adjGraph g)
{
    printf("图有%d个顶点,%d条边\n", g.n, g.m);
    printf("图的顶点是:");
    for (int i = 0; i < g.n; i++) {
        printf("%c ", g.vex[i]);
    }
    printf("\n图的邻接矩阵是:\n");
    for (int i = 0; i < g.n; i++) {
        for (int j = 0; j < g.n; j++) {
            printf("%4d", g.edge[i][j]);
        }
        printf("\n");
    }
}

void printDegree(adjGraph g)
{
    printf("图中每个顶点的入度是:\n");
    for (int i = 0; i < g.n; i++) {
        int indegree = 0;
            for (int j = 0; j < g.n; j++) {
                if (g.edge[j][i] == 1) {
                    indegree++;
                 }
            }
            printf("%c: %d \n", g.vex[i], indegree);
       }
       
  


    printf("图中每个顶点的出度是:\n");
    for (int i = 0; i < g.n; i++) {
        int outdegree = 0;
        for (int j = 0; j < g.n; j++) {
            if (g.edge[i][j] == 1) {
                outdegree++;
            }
        }
        printf("%c: %d \n", g.vex[i], outdegree);
        
    }

}

测试样例:

**有向带权图邻接矩阵建图和度数输出(含完整代码)

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#define N (100 + 5)
#define INF 0x3f3f3f3f//定义INF为一个十六进制无穷大常量

typedef char VexType; //顶点为字符类型
typedef int EdgeType;//邻接矩阵类型为整型

typedef struct {
    int n, m; //n个顶点,m条边
    VexType vex[N];//一维数组存放所有顶点的数据信息
    EdgeType edge[N][N];//邻接矩阵(二维数组存放图中所有顶点之间关系的信息)
} adjGraph;

//1.邻接矩阵建图
adjGraph createGraph();
//2.输出图的信息(顶点、邻接矩阵)
void print(adjGraph g);
//3.输出图中每个顶点的度数
void printDegree(adjGraph g);

int main()
{
    //1.建图
    adjGraph g = createGraph();
    //2.输出图的信息
    print(g);
    printDegree(g);
    return 0;
}


adjGraph createGraph()//建图
{
    adjGraph g;
    memset(g.edge, 0, sizeof(g.edge));//内存设置函数--创建图的过程中,所有元素初始化为0
    // g.edge 邻接矩阵
    //sizeof(g.edge) 数组占用的总字节数
    scanf("%d%d", &g.n, &g.m);//输入顶点数和边数
    getchar();//吸收换行符
    //1.输入n个顶点
    for (int i = 0; i < g.n; i++) {
        scanf("%c ", &g.vex[i]);
    }
    //2.输入m条边,按照邻接矩阵存图 
    // 将邻接矩阵初始化为INF
    for (int i = 0; i < g.m; i++) {
        for (int j = 0; j < g.m; j++) {
            g.edge[i][j] = INF;
        }
    }
    for (int i = 0; i < g.m; i++) {
        char v1, v2;
        int weight;
        scanf("\n%c %d %c", &v1, &weight, &v2);//读入当前边的2个顶点
        int n1 = v1 - 'A', n2 = v2 - 'A';
        //将顶点字符转换为对应的数组索引。
        // 假设顶点标签是大写字母'A'、'B'、'C'等,通过将其减去字符'A'的ASCII码值
        // 可以得到对应的数组索引(0、1、2等)。
       
        if (n1 == n2) {
            g.edge[n1][n2] = 0;
        }
        else {
            g.edge[n1][n2] = weight;
            g.edge[n2][n1] = INF; // 反方向的边权值设置为INF
        }
    }


    return g;
}

void print(adjGraph g)
{
    printf("图有%d个顶点,%d条边\n", g.n, g.m);
    printf("图的顶点是:");
    for (int i = 0; i < g.n; i++) {
        printf("%c ", g.vex[i]);
    }
    printf("\n图的邻接矩阵是:\n");
    for (int i = 0; i < g.n; i++) {
        for (int j = 0; j < g.n; j++) {
            if (i == j) printf("0 ");
            else if (g.edge[i][j] == INF)
            {
                printf("INF ");
           }
            else  {
                   printf("%-4d", g.edge[i][j]);
            }
                  
        
            
        }
        printf("\n");
    }
}

void printDegree(adjGraph g)
{
    printf("图中每个顶点的入度是:\n");
    for (int i = 0; i < g.n; i++) {
        int indegree = 0;
        for (int j = 0; j < g.n; j++) {
     
                  if (g.edge[j][i] != 0 && g.edge[j][i] != INF) {
                     indegree++;
                 }
    
            
        }
        printf("%c: %d \n", g.vex[i], indegree);
    }




    printf("图中每个顶点的出度是:\n");
    for (int i = 0; i < g.n; i++) {
        int outdegree = 0;
        for (int j = 0; j < g.n; j++) {
                if (g.edge[i][j] != 0&& g.edge[i][j] != INF) {
                    outdegree++;
                }
            }

        
        printf("%c: %d \n", g.vex[i], outdegree);

    }

}

样例:

2、邻接表存储方法

  对每一个顶点建立一个单链表,将同一个顶点发出的边链接在一个称为边链表的单链表中。

头插法:

五、图的遍历

六、最小生成树

      

七、最短路径问题

八、AOV网与拓扑排序

九、AOE网与关键路径

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

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

相关文章

内网安全—Windows系统内核溢出漏洞提权

系统内核溢出漏洞提权 往缓冲区中写入超出限定长度的内容&#xff0c;造成缓冲区溢出&#xff0c;从而破坏程序的堆栈进而运行自己精心准备的指定代码&#xff0c;达到攻击的目的。 分类&#xff1a; 堆溢出 栈溢出 查找补丁的方法 1、手工查找补丁情况 systeminfo Wmic qfe…

Redis设计与实现之Lua 脚本

目录 一、 Lua 脚本 1、初始化 Lua 环境 2、脚本的安全性 3、脚本的执行 4、 EVAL 命令的实现 定义 Lua 函数 执行 Lua 函数 5、 EVALSHA 命令的实现 二、 小结 一、 Lua 脚本 Lua 脚本功能是 Reids 2.6 版本的最大亮点&#xff0c;通过内嵌对 Lua 环境的支持&#xf…

加特兰Demo点迹数据Python读取和显示

加特兰当前主推的芯片&#xff0c;拿到了样件做了几个基本Demo测试&#xff0c;录取的点迹数据为txt文档&#xff0c;数据格式如下&#xff1a; FT 0.10 CMN1 263 CMN2 150 BNK 0 --- F 0 O 140/2/140!0/0/0/0/0/0.00! --- BK00: P 25.67, R 4.11, V 0.00, A -39.04,…

AR室内导航如何实现?技术与原理分析

随着科技的进步&#xff0c;我们生活中许多方面正在被重新定义。其中之一就是导航&#xff0c;尤其是室内导航。增强现实&#xff08;AR&#xff09;技术的出现为室内导航带来了革命性的变革。本文将深入探讨AR室内导航的技术与原理&#xff0c;以及它如何改变我们的生活方式。…

bat批处理:git上传更新

查看专栏目录 Network 灰鸽宝典专栏主要关注服务器的配置&#xff0c;前后端开发环境的配置&#xff0c;编辑器的配置&#xff0c;网络服务的配置&#xff0c;网络命令的应用与配置&#xff0c;windows常见问题的解决等。 文章目录 批处理背景批处理代码代码说明&#xff1a;使…

Hadoop Single Node Cluster的安装

Hadoop Single Node Cluster的安装 安装JDK查看java -version更新本地软件包安装JDK查看java安装位置 设置SSH无密码登录安装hadoop下载安装设置hadoop环境变量修改hadoop配置设置文件设置core-site.xml设置YARN-site.xml设置mapred-site.xml设置HDFS分布式文件系统创建并格式化…

[ CTF ]【天格】战队WriteUp-第七届“强网杯”全国安全挑战赛

第七届“强网杯”全国安全挑战赛 2023.12.16~2023.12.17 文章目录 【Misc】Pyjail ! Its myFILTER !!!easyfuzz谍影重重2.0签到Pyjail ! Its myRevenge !!!server_8F6C72124774022B.py 问卷调查 【Reverse】ezre 【Web】happygame 【强网先锋】石头剪刀布TrieSpeedUpezreez_fmt…

翻译: LLMs新的工作流程和新的机会 New workflows and new opportunities

生成人工智能正以多种方式引领着不仅仅是成本节约&#xff0c;更是收入增长。但是&#xff0c;就像生成人工智能这样的通用技术创造价值的方式有很多&#xff0c;谈论这些方式是很多的。但在这个视频中&#xff0c;我想看看一些我看到的新兴的&#xff0c;或者更常见的走向这种…

Java 8 中的 Stream:优雅的集合处理

Java 8 中的 Stream&#xff1a;优雅的集合处理 为什么需要 Stream&#xff1f;Stream 的特性Stream 基本操作1. 创建 Stream2. 中间操作2.1 过滤&#xff08;Filter&#xff09;2.2 映射&#xff08;Map&#xff09;2.3 截断&#xff08;Limit&#xff09; 3. 终端操作3.1 遍历…

STM32内部是怎么工作的

STM32是怎么工作的 1 从孩子他妈说起2 早期计算机的组成2.1 五大元件&#xff08;1&#xff09;第一个出场的是电容元件&#xff08;2&#xff09;第二个出场的是二极管&#xff08;3&#xff09;第三个出场的是电阻元件&#xff08;4&#xff09;第四个出场的是电感&#xff0…

其他配置相关安装

consul安装和配置 docker run -d -p 8500:8500 -p 8300:8300 -p 8301:8301 -p 8302:8302 -p 8600:8600/udp consul consul agent -dev -client0.0.0.0访问&#xff1a;http://192.168.0.102:8500/ DNS查询 dig 192.168.0.102 -p 8600 consul.service.consul SRVnacos安装 ht…

华为OS与麒麟OS:华为自研操作系统的对决

导言 在移动操作系统领域&#xff0c;华为OS和麒麟OS代表了华为在自主研发方面的努力。本文将深入探讨这两个操作系统的特点、竞争关系以及它们在用户体验、生态系统建设等方面的差异。 1. 背景与起源 华为OS的诞生&#xff1a; 华为OS是华为公司为应对外部环境而自主…

12.18_黑马数据结构与算法笔记Java

目录 thinking:orElse? thinking:map.computerifabsent? thinking&#xff1a;subString&#xff1f; 184 哈希表 问2 解释拆分 185 哈希算法 概述 186 哈希算法 Object.hashCode 187 哈希算法 String.hashCode 188 哈希算法 冲突测试 189 哈希算法 MurmurHash 190…

Linux操作系统:自由、稳定、强大的开源之光

导言 Linux操作系统作为一个开源的、多用户、多任务、支持多线程和多CPU的UNIX类操作系统&#xff0c;不仅在服务器领域占有显著份额&#xff0c;也逐渐在桌面和嵌入式系统中崭露头角。Linux操作系统的多样性体现在各种不同的发行版上&#xff0c;而Ubuntu、CentOS和Red Hat可以…

用Python编辑PDF文件:拆分合并、加密解密、页面编辑

文章目录 安装和初步使用合并与拆分页面编辑加密解密 安装和初步使用 PyPDF2支持拆分、合并、页面旋转、添加水印、加密解密等操作。支持pip安装&#xff0c;过程很丝滑。 pip install PyPDF2PyPDF2提供了PdfFileReader类&#xff0c;可用于读取PDF文件&#xff0c;其metadat…

用户行为分析遇到的问题-ubantu16,hadoop3.1.3

用户行为分析传送门 我的版本 ubantu16 hadoop 3.1.3 habse 2.2.2 hive3.1.3 zookeeper3.8.3 sqoop 1.46/1.47 我sqoop把MySQL数据往hbase导数据时候有问题 重磅&#xff1a;大数据课程实验案例&#xff1a;网站用户行为分析&#xff08;免费共享&#xff09; 用户行为分析-小…

使用ffmpeg将图片合成为mp4

首先在在图片文件夹输入cmd 这里确保已经安装ffmpeg并配置好环境变量。 然后这是我的文件夹目录&#xff1a; 将21张图片合成为mp4视频 这里使用如下命令&#xff1a; ffmpeg -framerate 1 -start_number 0 -i %d.png -c:v libx264 -pix_fmt yuv420p output.mp4 -framerat…

rabbitmq-常见七种消息队列-控制台界面管理-python-实现简单访问

文章目录 1.消息的基本概念1.1.生产者和消费者1.2.消息队列(Queue)1.3.交换机(Exchange)1.4.消息确认 2.七种队列模式2.1.简单模式(Hello World)2.2.工作队列模式(Work queues)2.3.发布订阅模式(Publish/Subscribe)2.4.路由模式(Routing)2.5.主题模式(Topics)2.6.远程过程调用(…

windows下wsl(ubuntu)ldconfig报错

错误 sudo ldconfig /sbin/ldconfig.real: Cant link /usr/lib/wsl/lib/libnvoptix_loader.so.1 to libnvoptix.so.1 /sbin/ldconfig.real: /usr/lib/wsl/lib/libcuda.so.1 is not a symbolic link解决&#xff1a; 处理 sudo ldconfig 报错 libcuda.so.1 is not a symbolic …

GZ015 机器人系统集成应用技术样题8-学生赛

2023年全国职业院校技能大赛 高职组“机器人系统集成应用技术”赛项 竞赛任务书&#xff08;学生赛&#xff09; 样题8 选手须知&#xff1a; 本任务书共 25页&#xff0c;如出现任务书缺页、字迹不清等问题&#xff0c;请及时向裁判示意&#xff0c;并进行任务书的更换。参赛队…