“这是我参与8月更文挑战的第23天,活动详情查看:8月更文挑战”
关注我,以下内容持续更新
前言
上一篇文章介绍了图的基本概念,本篇继续介绍图的存储方式--邻接矩阵表示法.
图的存储无法采用顺序结构是由图的特点来决定的,因为任何两个顶点之间都可能存在关系(边),无法通过存储位置表示这种任意的逻辑关系,所以图的存储无法采用顺序结构。那么如何存储图呢?图的存储一般有三种:邻接矩阵、邻接表、逆邻接表、十字链表、邻接多重表。
邻接矩阵(数组表示法)
基本思想:用一个一维数组存储图中顶点的信息,用一个二维数组(称为邻接矩阵)存储图中各顶点之间的邻接关系。假设图中有n个顶点,那么邻接矩阵是一个n*n的方阵。
1. 无向图的邻接矩阵
-
无向图的邻接矩阵的特点:主对角线上为0且一定是对称矩阵。
-
顶点i的度:邻接矩阵第i行(或列)非零元素的个数
-
如何判断顶点i和顶点j是否存在边: matrix[i][j]=1有边;matrix[i][j]=0没有边
-
如何求顶点 i 的所有邻接点:将数组中第i行元素扫描一遍,若matrix[i][j]为1,则顶点j为顶点i的邻接点。
2. 有向图的邻接矩阵
- 有向图的邻接矩阵不一定对称,例如有向完全图是对称的
- 如何求顶点 i 的出度:邻接矩阵第i行元素之和
- 如何求顶点 i 的入度:邻接矩阵第i列元素之和
- 如何判断从顶点i到顶点j是否存在边:matrix[i][j]是否为1
3. 网图的邻接矩阵
图的构造函数的实现
- 定义已知条件:图的顶点数组和边数组;
- 定义图的构造函数:需要传入两个参数<顶点数组和边数组>;
- 实现图的构造函数:
- 3.1 把传入的参数顶点数组和边数组赋值给图的顶点数组和边数组;
- 3.2 图的顶点个数进行赋值,等于传入的顶点数组的个数;
- 3.3 根据传入的边数组构造邻接矩阵;
- 3.3.1 初始化邻接矩阵,每个元素初始化为0
- 3.3.2 遍历传入的边数组,依次取出每一个边
- 3.3.3 取出边的起点start和终点end
- 3.3.4 将邻接矩阵的第start行第end列的元素值置为1,表示结点start和end之间存在边
- 3.3.5 将邻接矩阵的第end行第start列的元素值置为1,表示结点start和end之间存在边
- 3.3.1 初始化邻接矩阵,每个元素初始化为0
- 3.1 把传入的参数顶点数组和边数组赋值给图的顶点数组和边数组;
//MyGraph.h 文件
@interface MyGraph : NSObject
@property(assign,nonatomic)NSInteger vertexCount;//表示图的顶点个数
@property(strong,nonatomic)NSArray<NSString*>* vertexs;//表示图的顶点
@property(strong,nonatomic)NSArray<MyEdge*>* edges;//表示图的边
@property(strong,nonatomic)NSMutableArray<NSMutableArray<NSNumber*>*>* matrix;//用邻接矩阵存放图的各边的关系
- (instancetype)initWithVertexs:(NSArray *)vertexs edges:(NSArray<MyEdge*>*)edges;
@end
//MyGraph.m 文件
- (instancetype)initWithVertexs:(NSArray *)vertexs edges:(NSArray<MyEdge*>*)edges{
self = [super init];
if (self) {
//1.顶点的个数
self.vertexCount = vertexs.count;
//2.顶点
self.vertexs = vertexs;
//3.边
self.edges = edges;
//3.边的关系(邻接矩阵)
//3.1 初始化
self.matrix = [NSMutableArray array];
for (int i = 0; i<self.vertexCount; i++) {
NSMutableArray*arr = [NSMutableArray array];
for (int i = 0; i<self.vertexCount; i++) {
[arr addObject:@(0)];
}
[self.matrix addObject:arr];
}
//3.2 根据边edges给matrix赋值
for (int i = 0; i<edges.count; i++) {
MyEdge*edge = edges[i];
self.matrix[edge.start][edge.end] = @(1);
self.matrix[edge.end][edge.start] = @(1);
//self.matrix[edge.start][edge.end] = @(edge.weight);带权图这样赋值
}
}
return self;
}
边MyEdge的实现
//MyEdge.h 文件
@interface MyEdge : NSObject
/**边的一个顶点的下标*/
@property (nonatomic,assign) int start;
/**边的另一个顶点的下标*/
@property (nonatomic,assign) int end;
/**边的权重(非网图用不到权重)*/
@property (nonatomic,assign) int weight;
- (instancetype)initWithStart:(int)start end:(int)end weight:(int)weight;
@end
//MyEdge.m 文件
- (instancetype)initWithStart:(int)start end:(int)end weight:(int)weight
{
self = [super init];
if (self) {
self.start = start;
self.end = end;
self.weight = weight;
}
return self;
}
关注我
如果觉得我写的不错,请点个赞 关注我 您的支持是我更文最大的动力!