用三元组来表示矩阵的项
的时间复杂度O(columns*rows)更大,浪费了太多时间。
课本上对该算法的解释:
对于具体数学原理不甚理解,囧~~~
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 */
对于具体数学原理不甚理解,囧~~~