数据结构与算法(九)图链式存储

邻接表

度:无向图的度:顶点与邻接点连接的边就做度。有向图的度:指向顶点的边叫做入度,由顶点指向其他邻接点的边叫做出度

顶点:存储自身顶点信息和指向下一个临界点的指针

邻接点:保存临接点的存储下标和下一个邻接点的指向指针

存储方式:单向链接

无向图存储

arr[] = {a, d, c, b}  0 1 2 3

一个节点可以能多个邻接点,该节点可通过索引进行选择下一个邻接点选择哪个,如下图:

头表和邻接表

由上图可知,A有三个邻接点,分别是B C D。B有两个邻接点,分别是A C

在需要时,A可以直接指向C或D

有向图存储

有向图中,每一条边都有方向指向,分为出边和入边

在邻接表存储中只有出边没有入边

如上,只有A到E的边,没有E到A的边

带权图,只需同上加一个 权值表即可

在实际存储过程中,顶点和邻接点常以两种形式存储

邻接点:

struct AjdNode

{

    int index; 下标

    struct AdjNode* next; 指向下一个同类型的指针

}

顶点:

struct Node

{

    int data; 任意类型的数据域

    struct AjdNode* first;  指向第一个邻接点结构的指针

}

邻接表代码实现

const int g_maxcount = 1000;  定义一个最大节点数

int g_edge;

int g_nCount;

typedef struct _Node  按常理应有顶点和邻接点结构体,但此处省略写,两者共用一个结构体

{

    int nIndex;  既是邻接点下标也是data

    struct _Node * next;

}Node;

Node* head[g_nMaxCount]; 

声明一个数组,head相当于顶点,[]中相当于下标指向某一个顶点

void Create() 创建

{

    std::cout << "Input Node Count And Edge:" ;

    char cStart;  

    char cEnd; 边的两头,两个节点的字符

    std::cin >> g_nCount >> g_Edge; 输入要有多少个节点多少个边

    for(size_t i = 0; i < g_nEdge; i++)

    {

        std::cin >> cStart >> cEnd; 输入边的两头 如边ab ac

        int headIndex = cStart - 'a'; 转成数字编号,头节点的下标

        int nEdgeIndex = cEnd - 'a'; 尾节点的下标 input a - a = 0, b - a = 1 ,ASCII码应用

        Node* newNode = new Node; 进行插入

        newNode->nIndex = nEdgeIndex; 

        比如head是a edge是b,输入ab,a是顶点,b是邻接点,以邻接点b即b-a的数值当作下标从a指向b,具体理解如下

        newNode->next = head[nheadIndex];头插法,将新节点向下的指针,指向原有的第一个邻接点

        head[nheadIndex] = newNode;

    }

}

void print() 输出

{

    for(size_t i = 0; i < g_nCount; i++) 判断有多少个头

    {

        for(Node* temp = head[i]; temp != NULL; temp = temp->next) 遍历所有的头的邻接点

        临时节点指向头节点

        {

            std::out << "[" <<temp->nIndex << "]\t";

        }

        std::cout << std::endl;

    }

}

链式前向星

链式前向星由边集数组和头顶点数组组成,优点是可以快速访问一个点所有邻接点

边集数组 egde[i]  存储边

#define max 100

struct node  边集数组结构

{

    int to; 结尾的点

    struct node * next;

    int weight; 权值

}edge[max]; 定义有100个结构体

如下一个无向图

头节点数组

head[i] 存储下标 指向的第一个edge的下标

该图存储各个顶点信息 -1表示该顶点没有连向任何一个节点

边集数组便是将上述两个图结合起来,具体如下

最左边一列表示以哪个节点作为顶点

head表示该顶点指向的第一个边,如上图第一行head为2表示A指向了第2个边即edge[2]

上图中存储了各个边的信息 如第一条边存储了AB边,B是1,to是1

如上图边集数组A指向C之后A指向B,则在上图AC边next指向AB边

链式前向星代码实现

const int g_MaxCount = 100;

int g_nCount;  节点

int g_nEdge;  边

int g_nIndex;  索引

int g_nTo;  尾节点

int g_nWeight; 权值

int g_nHead; 顶点

int head[g_MaxCount]; 

struct Edge 边集数组

{

    int to;

    int weight;

    int next;

}e[g_MaxCount];

void init()

{

    memset(head, -1, (sizeof(int) * g_MaxCount));

    g_nHead = 0;

}

void add(int index; int to; int weight)

{

    e[g_nHead].to = to;

    e[g_nHead].weight = weight;

    e[g_Head].next = head[index];

    head[index] = g_nHead++; 

}

void print()

{

    for(size_t i = 1; i <= g_nCount; i++)

    {

        std::cout << i << ":\t";

        for(size_t j = head[i]; ~j; j = e[j].next) 遍历头数组 ~j相当于j != -1

        {

            std::cout << "[" << e[i].to << e[i].weight << "]\t";

        }

        std::cout << std::endl;

    }

}

应用:

std::cin >> g_nCount >> g_nEdge;

init();

for(size_t i = 1; i <= g_nEdge; i++)

{

    std::cin >> g_nIndex >> g_nTo >> g_nWeight;

    add(g_nIndex, g_nTo, g_nWeigh);

    add(g_nTo, g_nIndex, g_nWeigh);

}

print();

应用结果如下图

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

杨中科 ASP.NET MVC

ASP.NET Core 入门 什么是ASP.NET CORE 1、ASP.NET Core是.NET中做Web开发的框架 2、ASP.NET Core MVC 传统MVC项目&#xff0c;前后端都做在一起 3、ASP.NET Core Web API: 前后端分离、多端开发。(是属于MVC中的一部分) 4、ASPNET Core MVC其实包含Web API&#xff0c;不过…

RA4803SA (高稳定实时时钟模块)

汽车用RA4803SA&#xff0c;高稳定串行接口实时时钟模块内置频率可调32.768kHz晶体单元和DTCXO。1/100秒分辨率时间寄存器接口类型4线串行接口界面电压范围1.6V ~ 5.5V温度补偿电压范围2.2V至5.5V时钟电源电压范围1.6V ~ 5.5V可选时钟输出(32.768kHz, 1024Hz, 1Hz)各种功能包括…

了解一下InternLM1

InternLM 是在过万亿 token 数据上训练的多语千亿参数基座模型。通过多阶段的渐进式训练&#xff0c;InternLM 基座模型具有较高的知识水平&#xff0c;在中英文阅读理解、推理任务等需要较强思维能力的场景下性能优秀&#xff0c;在多种面向人类设计的综合性考试中表现突出。在…

PyTorch数据并行(DP/DDP)浅析

一直以来都是用的单机单卡训练模型&#xff0c;虽然很多情况下已经足够了&#xff0c;但总有一些情况得上分布式训练&#xff1a; 模型大到一张卡放不下&#xff1b;单张卡batch size不敢设太大&#xff0c;训练速度慢&#xff1b;当你有好几张卡&#xff0c;不想浪费&#xf…

IO进程线程Day4

1> 创建出三个进程完成两个文件之间拷贝工作&#xff0c;子进程1拷贝前一半内容&#xff0c;子进程2拷贝后一半内容&#xff0c;父进程回收子进程的资源 #include <myhead.h> //使用三个进程完成两个文件的拷贝工作 //两个子进程分别拷贝文件的上下两部分 //父进程回…

网络对讲终端 网络音频终端 网络广播终端SV-7011V使用说明

高速路sip广播对讲求助 隧道sip对讲调度SIP-7011 网络广播终端SV-7011 壁挂式对讲终端网络监听终端SIP广播终端 sip语音对讲终端SIP-7011 SV-7011网络对讲终端网络对讲、网络厂播、监听 SV-7101网络解码终端提供一路线路输出接功放或有源音箱。 SV-7102网络解码广播终端两…

华为欧拉安装部署:Oracle11g

一、环境准备 1、下载安装低版本的libaio包&#xff1b;libaio版本太高&#xff0c;会造成编译错误 查看libaio1库版本不能大于0.3.109 [oracles3 install]$ rpm -qa libaio libaio-0.3.110-12.el8.x86_64# 查看欧拉操作系统版本 [oraclelocalhost bin]$ cat /etc/os-release…

[蓝桥杯学习]​树上差分

差分 前缀和 sum_i sum_i-1 a_i 差分 diff_i a_i - a_i-1 差分的好处 点的差分 问题引入 解决问题 要用到差分的思想&#xff0c;每次从叶子向上的回溯&#xff0c;会让父结点子结点的cnt值&#xff0c;但是仅仅这样&#xff0c;还不行 回溯的过程中&#xff0c;LCA被…

uniapp中uview组件库丰富的Slider 滑动选择器的使用方法

目录 #平台差异说明 #基本使用 #设置最大和最小值 #设置步进值 #禁用状态 #自定义按钮的内容和样式 #自定义滑动选择器整体的样式 #此页面源代码地址 #API #Props #Slider Events 该组件一般用于表单中&#xff0c;手动选择一个区间范围的场景。 说明 该组件在H5&…

mysql四大引擎、账号管理以及建库

目录 一.数据库存储引擎1.1存储引擎的查看1.2InnoDB1.3MyISAM1.4 MEMORY1.5 Archive 二.数据库管理2.1元数据库分类2.2 操作2.3 MySQL库 三.数据表管理3.1三大范式3.2 整形3.3 实数3.4 字符串3.5 text&blob3.6 日期类型3.7 选中标识符 四.数据库账号管理4.1 查询用户4.2查看…

Spring中的工厂类

目录 1.ApplicationContext 4.2.BeanFactory 1.ApplicationContext ApplicationContext的实现类&#xff0c;如下图&#xff1a; ClassPathXmlApplicationContext&#xff1a;加载类路径下 Spring 的配置文件 FileSystemXmlApplicationContext&#xff1a;加载本地磁盘下 S…

企业级 npm 私有仓库部署方案

本文作者系360奇舞团前端开发工程师 淘宝 NPM 镜像站切换新域名时&#xff0c;放了一张知乎博主天猪的图片&#xff0c;如下&#xff1a; _图片来源&#xff1a;https://zhuanlan.zhihu.com/p/432578145 看着逐年增长的访问量&#xff0c;不禁让人感慨&#xff0c;npm 的出现&a…