数据结构与算法十一:2.1 图的存储结构---邻接矩阵方式

557 阅读4分钟

这是我参与8月更文挑战的第23天,活动详情查看:8月更文挑战

关注我,以下内容持续更新

数据结构与算法(一):时间复杂度和空间复杂度

数据结构与算法(二):桟

数据结构与算法(三):队列

数据结构与算法(四):单链表

数据结构与算法(五):双向链表

数据结构与算法(六):哈希表

数据结构与算法(七):树

数据结构与算法(八):排序算法

数据结构与算法(九):经典算法面试题

数据结构与算法(十):递归

数据结构与算法(十一):图

前言

上一篇文章介绍了图的基本概念,本篇继续介绍图的存储方式--邻接矩阵表示法.
图的存储无法采用顺序结构是由图的特点来决定的,因为任何两个顶点之间都可能存在关系(边),无法通过存储位置表示这种任意的逻辑关系,所以图的存储无法采用顺序结构。那么如何存储图呢?图的存储一般有三种:邻接矩阵、邻接表、逆邻接表、十字链表、邻接多重表。

邻接矩阵(数组表示法)

基本思想:用一个一维数组存储图中顶点的信息,用一个二维数组(称为邻接矩阵)存储图中各顶点之间的邻接关系。假设图中有n个顶点,那么邻接矩阵是一个n*n的方阵。

1. 无向图的邻接矩阵

截屏2021-08-22 13.28.02.png

  • 无向图的邻接矩阵的特点:主对角线上为0且一定是对称矩阵。

  • 顶点i的度:邻接矩阵第i行(或列)非零元素的个数

  • 如何判断顶点i和顶点j是否存在边: matrix[i][j]=1有边;matrix[i][j]=0没有边

  • 如何求顶点 i 的所有邻接点:将数组中第i行元素扫描一遍,若matrix[i][j]为1,则顶点j为顶点i的邻接点。

2. 有向图的邻接矩阵

截屏2021-08-22 13.35.21.png

  • 有向图的邻接矩阵不一定对称,例如有向完全图是对称的
  • 如何求顶点 i 的出度:邻接矩阵第i行元素之和
  • 如何求顶点 i 的入度:邻接矩阵第i列元素之和
  • 如何判断从顶点i到顶点j是否存在边:matrix[i][j]是否为1

3. 网图的邻接矩阵

image.png

图的构造函数的实现

  1. 定义已知条件:图的顶点数组和边数组;
  2. 定义图的构造函数:需要传入两个参数<顶点数组和边数组>;
  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之间存在边
//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;
}

关注我

如果觉得我写的不错,请点个赞 关注我 您的支持是我更文最大的动力!