数组和特殊矩阵
数组
数组是由一些相同类型的数据元素组成的有限序列,数组可以视为线性表的推广。
对于多维数组,其存储结构可以分为 按行优先 和 按列优先,前者以行为单位进行存储,存储为一行之后再存储下一行,后者按照列为单位。
特殊矩阵
压缩矩阵:为多个相同的元素只分配一个存储空间,对零元素不分配空间。
特殊矩阵:对于一些有特殊性质矩阵的优化,如对称矩阵、上(下)三角矩阵、对角矩阵等。
对称矩阵
对于一个 阶对称矩阵,只需要存储主对角线及其以上(下)的区域即可,若存储上三角,则每行存储的元素与其行数的对应关系如下:
若存储下三角,则对应关系为
则可以存储在长 的一维数组中。
对于矩阵的元素 ,求其与该一维数组 (下标从 0 开始)的对应关系:
- 由下 标可以得知其所在位置第 行与第 列;
- 若存储上三角,当 ,元素在上三角区域,前面 行的元素个数为 ,再加上当前列所在行在上三角区域前面的元素个数 ;若 时,由于其是对称矩阵,满足 ,只需要将 互换即可
- 若存储下三角,当 ,元素在下三角区域,前 行的元素个数为 ,其所在第 行下三角区域的第 个元素, 时同理,互换即可。
因此对应关系为
- 上三角
- 下三角
这里都减去 是因为数组下标从 开始。
上面是按照行优先的方式进行计算的,请自行推到按列优先的情况
三角矩阵
下(上)三角矩阵指的是上(下)三角区域(除去主对角线)全为同一常量,因此其存储方式与对称矩阵类似,只需要多额外存储该常量到最后一个元素即可。
下标对应公式可由上面的式子推出,不再赘述。
三对角矩阵
也称 带状矩阵,即主对角线及其上下一个副对角线的位置不为 ,其他元素都为 .
可以按行进行存储,除了第一行和最后一行是两个元素,其他行都是三个元素,因此一维数组的长度为
求矩阵元素坐标与数组下标的对应关系:
- 虽然三对角矩阵每行元素个数并不相同,但是可以将其首尾进行扩展,额外添加一个元素;
- 对于 合法的 第 行第 列的元素 来说,前 行有 个元素,由于有一个多添加的元素,减去一个 ,当前行前面共有 个有效元素,则对应关系为
合法 的坐标取值范围是 .
反过来,若得知一维数组的第 个元素,其对应的矩阵坐标为:
- 同上述方法,额外添加一个得
- 由于一行三个元素,则其行数为 ;
- 列数用式 反推 .
稀疏矩阵
非零元素远小于零元素的矩阵,一般认为非零元素占比小于 就可以视为稀疏矩阵, 此时采用常规方法存储会造成大量的浪费。
稀疏矩阵的常见存储格式如下:
- COO (Coordinate) 格式:以坐标形式存储稀疏矩阵的非零元素,每个非零元素包括其行号、列号和值;
- CSR (Compressed Sparse Row) 格式:通过将每一行的非零元素压缩存储来表示稀疏矩阵,其中需要三个数组:非零元素的值数组、每行第一个非零元素的列号数组和非零元素在值数组中的索引数组;
- CSC (Compressed Sparse Column) 格式:与 CSR 格式类似,但是通过按列存储非零元素来表示稀疏矩阵,需要三个数组:非零元素的值数组、每列第一个非零元素的行号数组和非零元素在值数组中的索引数组;
- DOK (Dictionary of Keys) 格式:使用字典数据结构存储稀疏矩阵的非零元素,其中字典的键是非零元素的坐标,值是对应的元素值
- BSR (Block Compressed Row) 格式:将稀疏矩阵划分为相等大小的块(block),然后针对每个块内的非零元素使用CSR格式进行压缩存储。
CSR 中,所有非零值存放在一个 数组中,并且使用一个相同长度的数组 存储其列号(一一对应),第三个矩阵被称为 ,其长度为矩阵行数,表示在原矩阵中每行第一个非零元素,在 数组中的位置。
CSC 类似,只是行列互换。
适合存储稀疏数组的数据结构有三元数组 和 十字链表。