数据结构--压缩矩阵及其转置

压缩矩阵及其转置

压缩矩阵

​ 矩阵,即二维数组,其可以采用顺序存储结构来存储其中的元素,但当矩阵阶数很高同时矩阵中有很多值相同的元素(或大多数元素的值为0)时,采用严格的顺序存储结构显然是相当浪费空间的,因为存储0元素或许多值相同的元素是没有意义的,因此为了节省空间,对此类矩阵通常采用压缩存储。

稀疏式矩阵(数值为0的元素数目远远多于非0元素数目且非0元素分布无规律的矩阵)的压缩存储,需要存储:①其中非0元素的值;②非0元素在矩阵中的行下标和列下标;③非0元素的个数;④矩阵总行数和总列数

例如:对图一稀疏矩阵进行压缩其结果如图二所示。

压缩前(图一)                                        压缩后(图二)

压缩矩阵存储代码

typedef int ElemType;

typedef struct Triple
{
    int i;  /* 非零元素行下标 */
    int j;  /* 非零元素列下标 */
    ElemType element;
} Triple, *TriplePtr;

typedef struct CompressedMatrix
{
    int rows,columns,numElements;   /* 行数、列数、非零元素个数 */
    TriplePtr elements;
} CompressedMatrix, *CompressedMatrixPtr;

初始化压缩矩阵

/* 初始化压缩矩阵 */
CompressedMatrixPtr initCompressedMatrix(int tempRows, int tempColumns, int tempElements, ElemType** tempData)
{
    CompressedMatrixPtr resultPtr = (CompressedMatrixPtr)malloc(sizeof(CompressedMatrix));
    resultPtr->rows = tempRows;
    resultPtr->columns = tempColumns;
    resultPtr->numElements = tempElements;
    resultPtr->elements = (TriplePtr)malloc(sizeof(Triple) * tempElements);
    for(int i = 0; i < tempElements; ++i)
    {
        resultPtr->elements[i].i = tempData[i][0];
        resultPtr->elements[i].j = tempData[i][1];
        resultPtr->elements[i].element = tempData[i][2];
    }
    return resultPtr;
}

压缩矩阵的转置

​ 矩阵转置是矩阵运算中极为重要的操作,但矩阵压缩后我们不能再像原来使用n * m的方式进行转置操作,此时其转置需要以下三部才能完成:

①将矩阵行数和列数互换

②将三元组表中的i行和j列互换

③不断遍历存储矩阵的三元组表,每次取出表中j列最小的一组,互换行标和列标的值,并按 次序存储到新的三元组表中

算法图示

在这里插入图片描述

代码描述:

/* 转置压缩矩阵 */
CompressedMatrixPtr transposeCompressedMatrix(CompressedMatrixPtr tempPtr)
{
    int tempColumn,tempPosition;
    int* tempColumnCounts = (int*)malloc(tempPtr->columns * sizeof(int));
    int* tempOffsets = (int*)malloc(tempPtr->columns * sizeof(int));
    for(int i = 0; i < tempPtr->columns; ++i)
    {
        tempColumnCounts[i] = 0;
    }
    CompressedMatrixPtr resultPtr = (CompressedMatrixPtr)malloc(sizeof(CompressedMatrix));
    resultPtr->rows = tempPtr->columns;
    resultPtr->columns = tempPtr->rows;
    resultPtr->numElements = tempPtr->numElements;
    resultPtr->elements = (TriplePtr)malloc(sizeof(Triple) * tempPtr->numElements);
    for(int i = 0; i < tempPtr->numElements; ++i)
    {
        tempColumnCounts[tempPtr->elements[i].j]++;
    }
    tempOffsets[0] = 0;
    for(int i = 1; i < tempPtr->columns; ++i)
    {
        tempOffsets[i] = tempOffsets[i-1] + tempColumnCounts[i-1];
        printf("tempOffsets[%d] = %d \n",i,tempOffsets[i]);
    }
    for(int i = 0; i < tempPtr->numElements; ++i)
    {
        tempColumn = tempPtr->elements[i].j;
        tempPosition = tempOffsets[tempColumn];
        resultPtr->elements[tempPosition].i = tempPtr->elements[i].j;
        resultPtr->elements[tempPosition].j = tempPtr->elements[i].i;
        resultPtr->elements[tempPosition].element = tempPtr->elements[i].element;
        tempOffsets[tempColumn]++;
    }
    return resultPtr;
}

打印压缩矩阵

/* 打印压缩矩阵 */
void printCompressedMatrix(CompressedMatrixPtr tempPtr)
{
    for(int i = 0; i < tempPtr->numElements; ++i)
    {
        printf("(%d, %d): %d\n",tempPtr->elements[i].i,tempPtr->elements[i].j,tempPtr->elements[i].element);
    }
}

完整代码

#include <stdio.h>
#include <malloc.h>

typedef int ElemType;

typedef struct Triple
{
    int i;  /* 非零元素行下标 */
    int j;  /* 非零元素列下标 */
    ElemType element;
} Triple, *TriplePtr;

typedef struct CompressedMatrix
{
    int rows,columns,numElements;   /* 行数、列数、非零元素个数 */
    TriplePtr elements;
} CompressedMatrix, *CompressedMatrixPtr;

/* 初始化压缩矩阵 */
CompressedMatrixPtr initCompressedMatrix(int tempRows, int tempColumns, int tempElements, ElemType** tempData)
{
    CompressedMatrixPtr resultPtr = (CompressedMatrixPtr)malloc(sizeof(CompressedMatrix));
    resultPtr->rows = tempRows;
    resultPtr->columns = tempColumns;
    resultPtr->numElements = tempElements;
    resultPtr->elements = (TriplePtr)malloc(sizeof(Triple) * tempElements);
    for(int i = 0; i < tempElements; ++i)
    {
        resultPtr->elements[i].i = tempData[i][0];
        resultPtr->elements[i].j = tempData[i][1];
        resultPtr->elements[i].element = tempData[i][2];
    }
    return resultPtr;
}

/* 打印压缩矩阵 */
void printCompressedMatrix(CompressedMatrixPtr tempPtr)
{
    for(int i = 0; i < tempPtr->numElements; ++i)
    {
        printf("(%d, %d): %d\n",tempPtr->elements[i].i,tempPtr->elements[i].j,tempPtr->elements[i].element);
    }
}

/* 转置压缩矩阵 */
CompressedMatrixPtr transposeCompressedMatrix(CompressedMatrixPtr tempPtr)
{
    int tempColumn,tempPosition;
    int* tempColumnCounts = (int*)malloc(tempPtr->columns * sizeof(int));
    int* tempOffsets = (int*)malloc(tempPtr->columns * sizeof(int));
    for(int i = 0; i < tempPtr->columns; ++i)
    {
        tempColumnCounts[i] = 0;
    }
    CompressedMatrixPtr resultPtr = (CompressedMatrixPtr)malloc(sizeof(CompressedMatrix));
    resultPtr->rows = tempPtr->columns;
    resultPtr->columns = tempPtr->rows;
    resultPtr->numElements = tempPtr->numElements;
    resultPtr->elements = (TriplePtr)malloc(sizeof(Triple) * tempPtr->numElements);
    for(int i = 0; i < tempPtr->numElements; ++i)
    {
        tempColumnCounts[tempPtr->elements[i].j]++;
    }
    tempOffsets[0] = 0;
    for(int i = 1; i < tempPtr->columns; ++i)
    {
        tempOffsets[i] = tempOffsets[i-1] + tempColumnCounts[i-1];
        printf("tempOffsets[%d] = %d \n",i,tempOffsets[i]);
    }
    for(int i = 0; i < tempPtr->numElements; ++i)
    {
        tempColumn = tempPtr->elements[i].j;
        tempPosition = tempOffsets[tempColumn];
        resultPtr->elements[tempPosition].i = tempPtr->elements[i].j;
        resultPtr->elements[tempPosition].j = tempPtr->elements[i].i;
        resultPtr->elements[tempPosition].element = tempPtr->elements[i].element;
        tempOffsets[tempColumn]++;
    }
    return resultPtr;
}

/* 测试 */
void compressedMatrixTest()
{
    CompressedMatrixPtr tempPtr1, tempPtr2;
    int tempElements;
    tempElements = 4;
    ElemType** tempMatrix1 = (ElemType**)malloc(sizeof(ElemType*) * tempElements);
    for(int i = 0; i < tempElements; ++i)
    {
        tempMatrix1[i] = (ElemType*)malloc(sizeof(ElemType) * 3);
    }
    int tempMatrix2[4][3] = {{0,0,2},{0,2,3},{2,0,5},{2,1,6}};
    for(int i = 0; i < tempElements; ++i)
    {
        for(int j = 0; j < 3; ++j)
        {
            tempMatrix1[i][j] = tempMatrix2[i][j];
        }
    }
    tempPtr1 = initCompressedMatrix(2,3,4,tempMatrix1);
    printf("初始化后\n");
    printCompressedMatrix(tempPtr1);
    tempPtr2 = transposeCompressedMatrix(tempPtr1);
    printf("转置后\n");
    printCompressedMatrix(tempPtr2);
}

int main()
{
	compressedMatrixTest();
	return 0;
}

运行结果

初始化后
(0, 0): 2
(0, 2): 3
(2, 0): 5
(2, 1): 6
tempOffsets[1] = 2
tempOffsets[2] = 3
转置后
(0, 0): 2
(0, 2): 5
(1, 2): 6
(2, 0): 3
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黎子想写好代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值