利用三元组对稀疏矩阵进行压缩存储并实现矩阵的转置运算_若采用三元组压缩技术存储稀疏矩阵

对象篇

模块化编程-自研模块加载器

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

我们假设在m*n的矩阵中,有t个元素不为0,令a=t/(m*n),称a为矩阵的稀疏因子,通常认为a<=0.05时称为稀疏矩阵
为了节省存储空间,我们对稀疏矩阵进行压缩存储——只存储稀疏矩阵的非零元。因此,除了存储非零元的值之外,还必须同时记下它所在行和列的位置,反之,一个三元组(i, j, aij)惟一确定了矩阵A的一个非零元。由此,稀疏矩阵可由表示非零元的三元组及其行列数惟一确定。
例如,下列三元组表
((1,2,12),(1,3,9),(3,1,-3),(3,6,14),(4,3,24),(5,2,18),(6115),(6,4,7))
加上(6,7)这一对行、列值便可作为下图矩阵M的另一种描述。
这里写图片描述
假设以顺序存储结构来表示三元组表,则可得稀疏矩阵的一种压缩存储方式——我
们称之为三元组顺序表。
这里写图片描述
在此,data域中表示非零元的三元组是以行序为主序顺序排列的。下面将讨论在这种压缩存储结构下如何实现矩阵的转置运算
显然,一个稀疏矩阵的转置矩阵仍然是稀疏矩阵。假设a和b是Tsmatrix型的变量,分别表示矩阵M和T。那么,如何由a得到b呢?
从分析a和b之间的差异可见只要做到:(1)将矩阵的行列值相互交换;(2)将每个三
元组中的I和j相互调换;(3)重排三元组之间的次序便可实现矩阵的转置。前二条是容易做到的,关键是如何实现第三条。即如何使b. data中的三元组是以T的行(M的列)为主序依次排列的。
下面我讲一个自认为十分巧妙也是很好理解的一种处理办法:
我们在a中即矩阵M中,以列序为主序对非零元进行顺序排列,很好理解,这就是M进行转置运算后得到的矩阵T中以行序为主序对非零元进行顺序排列相应的序列。即实现了b. data中的三元组是以T的行(M的列)为主序依次排列的。
思路如下:
为了确定a中非零元以列序为主序进行顺序排列的序列,在转置前,应先求得M的每一列中非零元的个数,进而求得每一列的第一个非零元在b. data中应有的位置。
在此,需要附设num和cpot两个向量。num[col]表示矩阵M中第col列中非零元
的个数,cpot[col]指示M中第col列的第一个非零元在b. data中的恰当位置。代码实现如下:

       for(col=0;col<M.ru;col++) num[col]=0;
        for(t=0;t<M.tu;t++) ++num[M.data[t].j];//求出每一列中非零元的个数
        cpot[0]=0;//第一列的第一个非零元计数为0
        for(col=1;col<M.tu;col++){
            cpot[col]=cpot[col-1]+num[col-1];//从第二列开始,每一列第一个非零元序列为上一列第一个非零元序列加上是上一列的非零元数
        }
        for(t=0;t<M.tu;t++){
            col=M.data[t].j;
            q=cpot[col];
            T.data[q].i=M.data[t].i;
            T.data[q].j=M.data[t].j;
            T.data[q].e=M.data[t].e;
            ++cpot[col];//这一列下一个非零元序列在是一个基础上加一
        }

全部参考代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
#define ElemType int 
#define MAXSIZE 100
typedef struct{
    int i,j;
    ElemType e;
} Triple;
typedef struct{
    Triple data[MAXSIZE];
    int mu,ru,tu;//矩阵的行数、列数和非零元个数 
}TSMatrix;
int main(){
    TSMatrix M,T;
    int col,num[100],cpot[100],t,q,i,j,m,n;
    int b[7][6];
    int a[6][7]={
         1,12,9,0,0,0,0,
         0, 0,0,0,0,0,9,
        -3,0,0,0,0,14,0,
         0,0,24,0,0,0,0,
         0,18,0,0,0,9,0,
        15,0,0,-7,0,0,9     
    }; 
    M.mu=6;
    M.ru=7;
    M.tu=0;
    for(i=0;i<6;i++){
        for(j=0;j<7;j++){
            if(a[i][j]!=0){


### 最后:

总结来说,面试成功=基础知识+项目经验+表达技巧+运气。我们无法控制运气,但是我们可以在别的地方花更多时间,每个环节都提前做好准备。

面试一方面是为了找到工作,升职加薪,另一方面也是对于自我能力的考察。能够面试成功不仅仅是来自面试前的临时抱佛脚,更重要的是在平时学习和工作中不断积累和坚持,把每个知识点、每一次项目开发、每次遇到的难点知识,做好积累,实践和总结。

**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/topics/618166371)**

![](https://img-blog.csdnimg.cn/img_convert/6c2aeb959ce63ed49d79e6e8c1254ad8.webp?x-oss-process=image/format,png)

学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/topics/618166371)**

[外链图片转存中...(img-tNH54PIx-1715225839570)]

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值