稀疏矩阵的普通转置与快速转置算法

稀疏矩阵的普通转置与快速转置算法

一般来说,对于系数矩阵,我们使用三元组来存储。即就是将矩阵的所有非零元素的三元组存放在一个顺序表中,如图所示:

注意一个转置的前提:该顺序表是排好序的,即行优先,列其次。

一、普通转置


这种算法比较简单,也很容易想到:

       

算法思想:

       对 M.data 从头至尾扫描:
              « 第一次扫描时,将 M.data 中列号为 1 的三元组赋值到 T.data
              « 第二次扫描时,将 M.data 中列号为 2 的三元组赋值到 T.data
              « 依此类推,直至将 M.data 所有三元组赋值到 T.data

代码

//转置运算算法
void transpose2(TSMatrix M, TSMatrix  T)  
{//采用三元组表存储表示,求稀疏矩阵M的转置矩阵T    
     T.rows=M.rows;  T.size=M.size;;     
     q=1;   // q为当前三元组在T.data[ ]存储位置(下标)     
     for (col=1; col<=M.cols;  ++col)          
           for (p=1;  p<=M.size;  ++p) 
                    if (M.data.get(p).j= =col){ 
                          T.data.get(q).i =M.data.get(p).j;
                          T.data.get(q).j=M.data.get(p).i;                                                
                          T.data.get(q).value=M.data.get(p).value; 
                          ++q;
                    }
}


二、快速转置


这种算法往往理解起来较为困难。

算法思想:



       « 按M中三元组次序转置,转置结果放入T中恰当位置。

       « 关键
              v 预先确定M中每一列第一个非零元在T中位置
              v 为确定这些位置,转置前应先求得M的每一列中非零元个数

       « 实现:设两个数组 num[ ] cpos[ ]
              v num[col] :存储 M 中第 col 列非零元个数
              v cpos[col] :存储 M 中第 col 列第一个非零元三元组在 T.data 中的位置

       « cpos[col] 的计算方法:
              v cpos[1]=1
              v cpos[col]=cpos[col-1]+num[col-1] (2<=col <=M.nu)




代码:

//稀疏矩阵快速转置算法(C语言描述)
void  Transpose (TSMatrix M, TSMatrix &T) 
{ //采用三元组顺序表存储表示,求稀疏矩阵M的转置矩阵T
       T.m=M.n; T.n=M.m; T.tu=M.tu;    //将M的行数赋值给T的列数,将M的列数赋值给T的行数,非零元素总数也赋值过去
       for (col=1; col<=M.nu; ++col)    num[col]=0;    //初始化假设原三元组每一列都是0
       for (t=1; t<=M.tu; ++t)     ++num[M.data[t].j];  //枚举每一个非0元素, M.data[t].j 为其相应的列
       cpot[1]=1;                                       //求第 col列中第一个非零元在T.data中的序号
       for(col=2; col<=M.t;  ++col)                     //<span style="color:black;"><span style="color:black;"><span style="color:black;">存储</span><span style="color:black;">M</span><span style="color:black;">中第</span><span style="color:black;">col</span><span style="color:black;">列第一个非零元三元组在</span><span style="color:black;">T.data</span><span style="color:black;">中的位置</span></span></span>
           cpot[col]=cpot[col-1]+num[col-1];    
       for(p=1; p<M.tu;  ++p) {                         //枚举所有的三元组  
         col=M.data[p].j;                               //将第i个三元组的列数赋值给col
         q=cpot[col];                                   
         /*取出cpot数组中cpot[col]的值,注意,这里很重要:因为在顺序表中,所有的行元素的大小已经是依次排好的,
           所以我们遍历到的这个三元组时,当其与其后面的拥有相同列元素的三元组进行比较的时候,它一定是最小的,
           所以应该放在前面时,所以我们取完这个值之后,将cpot[col]的值+1,即可在下面的遍历中搜索到与之邻近的
           值,正好下标已经+1,直接添加上去即可*/
         T.data[q].i=M.data[p].j;  
         T.data[q].j=M.data[p].i; 
         T.data[q].value=M.data[p].value;//赋值操作   
         ++cpot[col];        //下标记录+1
     }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值