再谈图的存储方式(邻接矩阵,邻接表,前向星)

2024-06-11 00:32

本文主要是介绍再谈图的存储方式(邻接矩阵,邻接表,前向星),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.邻接矩阵

1.存图思想

使用一个矩阵来描述一个图,对于矩阵的第i行第j列的值,表示编号为i的顶点到编号为j的顶点的权值。

2.代码实现

// 最大顶点数
const int V = 1000;// 邻接矩阵的定义
// mat[i][j] 表示 顶点'i'到顶点'j'的权值
int mat[V][V];// 邻接矩阵的初始化操作
// 假设权值为零表示没有该边
memset(mat, 0, sizeof(mat))// 增加边
// 新增顶点'i'到顶点'j'的边,权值为w
mat[i][j] = w;//遍历邻接边
for(int i=0;i<n;i++)
{for(int j=0;j<n;j++){if(mat[i][j]!=0)//doing something.}
}

2.邻接表

1.存图思想

邻接矩阵对于每个顶点使用定长的数组来存储以该点出发的边的情况。第i个数组的第j个值存储的是从顶点i到顶点j的边的权值。 
邻接表则是对于每个顶点使用不定长的链表来存储以该点出发的边的情况。因此对第i个链表的第j个值实际上存储的是编号为i的顶点出发的第j条边的情况。

2.代码实现

在ACM题目中,动态的数据结构一般是不被推荐的,因为动态开辟内存比较消耗时间,且写起来复杂容易出错。 
大部分情况我们使用C++STL里的vector作为链表来实现图的邻接表。
// 最大顶点数
const int V = 100000;// vector实现的邻接表的定义
// 不考虑边权,存储类型为int型
vector<int> e[V];
// 若考虑边权,则定义一个结构,vector也为结构体类型
struct node{int v,int w};//存储边的终点和边的权值
vector<node> e[V];
//也可以用一个数组或vector单独存边的信息,然后在邻接表vector中记录每个点邻接边的编号// 邻接表的初始化操作
for(int i=0;i<n;i++)
{e[i].clear();
}// 增加边
//不考虑边权
e[i].push_back(j);
//考虑边权
e[i].push_back(node(j,w));//遍历邻接边
for (int j=0; j<(int)e[i].size(); ++j) {int k=e[i][j];//第j条边为[i,k]//ornode &e=e[i][j];//第j条边为[i,e.v,e.w]// do something.
}

3.前向星

1.存图思想

前向星是一种特殊的边集数组,我们把边集数组中的每一条边按照起点从小到大排序,如果起点相同就按照终点从小到大排序,  并记录下以某个点为起点的所有边在数组中的起始位置和存储长度,那么前向星就构造好了. 
用len[i]来记录所有以i为起点的边在数组中的存储长度. //不用len数组也可以  
用head[i]记录以i为边集在数组中的第一个存储位置.

2.代码实现

一般不用不写了。。。

4.链式前向星

1.存图思想

我们建立边结构体为:
struct Edge
{int next;int to;int w;
};
其中edge[i].to表示第i条边的终点,edge[i].next表示与第i条边同起点的下一条边的存储位置,edge[i].w为边权值. 
另外还有一个数组head[],它是用来表示以i为起点的第一条边存储的位置,实际上你会发现这里的第一条边存储的位置其实是在以i为起点的所有边的最后输入的那个编号.head[]数组一般初始化为-1。 

2.代码实现

// 最大顶点数
const int V = 1000;
const int E = 10000;struct Edge
{int next;int to;int w;
};
Edge edge[E];
int head[V];//初始化
memset(head,0xff,sizeof(head));
memset(edge,0,sizeof(edge));//增加边
void add(int u,int v,int w) 
{  //cnt为边计数edge[cnt].w = w;  edge[cnt].to = v;  edge[cnt].next = head[u];  head[u] = cnt++;  
} //遍历边
for(int i=1;i<=n;i++)
{for(int k=head[i];k!=-1;k=edge[k].next){//doing something.}
}


相关资料:
1.链式前向星及其简单应用 | Malash's Blog
2.前向星与链式前向星 | 学步园
3.ACM图论之存图方式 | 剑紫青天

这篇关于再谈图的存储方式(邻接矩阵,邻接表,前向星)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1049704

相关文章

Linux之systemV共享内存方式

《Linux之systemV共享内存方式》:本文主要介绍Linux之systemV共享内存方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、工作原理二、系统调用接口1、申请共享内存(一)key的获取(二)共享内存的申请2、将共享内存段连接到进程地址空间3、将

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推

C#使用StackExchange.Redis实现分布式锁的两种方式介绍

《C#使用StackExchange.Redis实现分布式锁的两种方式介绍》分布式锁在集群的架构中发挥着重要的作用,:本文主要介绍C#使用StackExchange.Redis实现分布式锁的... 目录自定义分布式锁获取锁释放锁自动续期StackExchange.Redis分布式锁获取锁释放锁自动续期分布式

Java对象转换的实现方式汇总

《Java对象转换的实现方式汇总》:本文主要介绍Java对象转换的多种实现方式,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Java对象转换的多种实现方式1. 手动映射(Manual Mapping)2. Builder模式3. 工具类辅助映

关于MongoDB图片URL存储异常问题以及解决

《关于MongoDB图片URL存储异常问题以及解决》:本文主要介绍关于MongoDB图片URL存储异常问题以及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录MongoDB图片URL存储异常问题项目场景问题描述原因分析解决方案预防措施js总结MongoDB图

Spring Boot读取配置文件的五种方式小结

《SpringBoot读取配置文件的五种方式小结》SpringBoot提供了灵活多样的方式来读取配置文件,这篇文章为大家介绍了5种常见的读取方式,文中的示例代码简洁易懂,大家可以根据自己的需要进... 目录1. 配置文件位置与加载顺序2. 读取配置文件的方式汇总方式一:使用 @Value 注解读取配置方式二

JAVA保证HashMap线程安全的几种方式

《JAVA保证HashMap线程安全的几种方式》HashMap是线程不安全的,这意味着如果多个线程并发地访问和修改同一个HashMap实例,可能会导致数据不一致和其他线程安全问题,本文主要介绍了JAV... 目录1. 使用 Collections.synchronizedMap2. 使用 Concurren

C# foreach 循环中获取索引的实现方式

《C#foreach循环中获取索引的实现方式》:本文主要介绍C#foreach循环中获取索引的实现方式,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、手动维护索引变量二、LINQ Select + 元组解构三、扩展方法封装索引四、使用 for 循环替代

将Java程序打包成EXE文件的实现方式

《将Java程序打包成EXE文件的实现方式》:本文主要介绍将Java程序打包成EXE文件的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录如何将Java程序编程打包成EXE文件1.准备Java程序2.生成JAR包3.选择并安装打包工具4.配置Launch4

springboot上传zip包并解压至服务器nginx目录方式

《springboot上传zip包并解压至服务器nginx目录方式》:本文主要介绍springboot上传zip包并解压至服务器nginx目录方式,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录springboot上传zip包并解压至服务器nginx目录1.首先需要引入zip相关jar包2.然