稀疏矩阵的转置

用三元组来表示矩阵的项
typedef struct  {
    int col;//列
    int row;//行
    int value;
} term ;

矩阵的转置:将矩阵a转置保存在矩阵b中

void transpose(term a[],term b[]){
    int n,i,j,currentb;
    n = a[0].value;
    b[0].row = a[0].col;
    b[0].row = a[0].row;
    b[0].value = n;
    if (n>0) {/*非零矩阵*/
        currentb = 1;
        for (i=0; i<a[0].col; i++) {
            /* 按a的列转置 */
            for (j=1; j<n; j++) {
                /* 找出当前列的所有元素 */
                if (a[j].col == i) {
                    /* 元素是当前列的,加入b */
                    b[currentb].row = a[j].col;
                    b[currentb].col = a[j].row;
                    b[currentb].value = a[j].value;
                    currentb++;
                }
            }
        }
    }
}
上面函数的时间复杂度为O(columns*elements),当元素为columns*rows量级时,时间复杂度就变为了O(columns^2*rows)。这时效率反而比
for( j = 0;j < columns ; j++ )
for(  i= 0; i < rows; i++)
b[j][i] = a[i][j];

的时间复杂度O(columns*rows)更大,浪费了太多时间。

算法优化:

void fast_transpose(term a[],term b[]){
    /* 将a的转置矩阵存放在b中 */
    int row_terms[MAX_COL],starting_pos[MAX_COL];
    int i,j,num_cols = a[0].col,num_terms = a[0].value;
    b[0].row = num_cols;
    b[0].col = a[0].row;
    b[0].value = num_terms;
    if (num_terms > 0) {
        /* 非零矩阵 */
        for (i=0; i<num_cols; i++) {
            row_terms[i] = 0;
        
        }
        for (i=1; i<=num_terms; i++) {
            row_terms[a[i].col]++; /* b矩阵中,i行的元素个数为row_terms[i] */
        }
        starting_pos[0] = 1;
        for (i=1; i<=num_terms; i++) {
            starting_pos[i] = starting_pos[i-1] + row_terms[i-1];
        }
        for (i=1; i<= num_terms; i++) {
            j = starting_pos[a[i].col]++;
            b[j].row = a[i].col;
            b[j].col = a[i].row;
            b[j].value = a[i].value;
        }
    }
}

课本上对该算法的解释:

可以确定原矩阵中每一列的元素个数,可以得到转置矩阵每一行的起始位置,可以将原矩阵的元素依次转移到转置矩阵中恰当的位置

补充:

#define MAX_COL 50 /* 最大列数 +1 */

对于具体数学原理不甚理解,囧~~~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值