Skip to content

三元组

稀疏矩阵中非零元的个数太少,所以只需要存储矩阵的非零元就可以了。这就是矩阵的压缩存储,对应的实现方式是三元组表与十字链表。

三元组法的思想是,在表示和定位一个非零元的时候,不仅需要记录该元素的值,还要知道它的位置,也就是第几行、第几列。没有表示到的位置的值自然就是 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; // 返回成功
}

三元组表的转置

但是我们希望这个表是按照行号或是列号的顺序来排列的。虽然可以先乱序存储,再对整个表进行排序,但是大多数的排序,时间复杂度都会很高。

所以自然就需要找到一种方式,天然就可以把非零元三元组按序存储。

十字链表

广义表