三元组
稀疏矩阵中非零元的个数太少,所以只需要存储矩阵的非零元就可以了。这就是矩阵的压缩存储,对应的实现方式是三元组表与十字链表。
三元组法的思想是,在表示和定位一个非零元的时候,不仅需要记录该元素的值,还要知道它的位置,也就是第几行、第几列。没有表示到的位置的值自然就是 0 了。
包含了行、列以及元素值三者信息的数据结构就叫三元组。
c
// 三元组
typedef struct
{
int i, j; // 行号和列号
ElemType e; // 元素值
} Triple;
把这些三元组建立一个表存起来,这个表叫做三元组表。这个三元组表,将会存储矩阵所有非零元的三元组。
c
// 三元组表
typedef struct
{
Triple data[MAXSIZE + 1]; // 非零元素的三元组表,data[0]未用
int mu, nu, tu; // 矩阵的行数、列数和非零元素个数
} TSMatrix;
Details
c
// 三元组表
void PrintMatrix(int mat[][COLS], int mu, int nu); // 打印矩阵
Status CreateTSMatrixByMat(int mat[][COLS], int mu, int nu, TSMatrix &M); // 创建三元组表
void PrintSMatrix(TSMatrix M); // 打印三元组表
Status TransposeSMatrix(TSMatrix M, TSMatrix &T); // 按列转置
Status RowTransposeSMatrix(TSMatrix M, TSMatrix &T); // 按行转置
void PrintNewMatByT(TSMatrix T); // 打印转置后的矩阵
三元组表的建立
同时还要求,三元组表是按顺序排列的,要么按行,要么按列。
cpp
// 建立三元组表
Status CreateTSMatrixByMat(int mat[][COLS], int mu, int nu, TSMatrix &M)
{
M.mu = mu; // 行数
M.nu = nu; // 列数
M.tu = 0; // 非零元素个数,初始化为0
// 遍历矩阵,找出非零元素
for (int i = 0; i < mu; ++i)
{
for (int j = 0; j < nu; ++j)
{
if (mat[i][j] != 0)
{
M.tu++; // 计数非零元素
M.data[M.tu].i = i + 1; // 行号(从1开始)
M.data[M.tu].j = j + 1; // 列号(从1开始)
M.data[M.tu].e = mat[i][j]; // 元素值
}
}
}
return 1; // 返回成功
}
三元组表的转置
但是我们希望这个表是按照行号或是列号的顺序来排列的。虽然可以先乱序存储,再对整个表进行排序,但是大多数的排序,时间复杂度都会很高。
所以自然就需要找到一种方式,天然就可以把非零元三元组按序存储。