一般的稀疏矩阵转置算法
void transpose(term* a, term *b)
{
int n;
int currentb;
n = a[0].value;
b[0].row = a[0].col;
b[0].col = a[0].row;
b[0].value = n;
if (n > 0) //非零矩阵
{
currentb = 1;
for (int i = 0; i < a[0].col; ++i)
{
//按a的列转置
for (int j = 1; j <= n; ++j)
{
if (a[j].col == i)//当前列的所有元素
{
b[currentb].row = a[j].col;
b[currentb].col = a[j].row;
b[currentb].value = a[j].value;
++currentb;
}
}
}
}
return;
}
这个算法的渐进时间复杂度为O(col*element)。
当这个矩阵元素达到col*row级别时;渐进时间复杂度为O(col^2*row),节省了空间的同时浪费了太多的时间。对于三元组序列表示的矩阵,可以在O(cols + element)时间内将其转置,通过增加少许储存空间,获取更好的转置算法。如下
#include <stdio.h>
#define MAX_TERMS 101
typedef struct{
int row = 0;
int col = 0;
int value = 0;
} term;
void initSparseMatrix(int c[][10])//为了方便,直接这样初始化了原始的稀疏矩阵
{
for (int i = 0; i < 10; ++i)
{
for (int j = 0; j < 8; ++j)
{
if(i == j + 1)
c[i][j] = i * j + 1;
else
c[i][j] = 0;
}
}
return;
}
void saveMatrixIntoArray(term* arr, int c[][10])//将稀疏矩阵储存到数组a中
{
int pos = 1;
for (int i = 0; i < 10; ++i)
{
++arr[0].row;
for (int j = 0; j < 8; ++j)
{
if (c[i][j] != 0)
{
arr[pos].row = i;
arr[pos].col = j;
arr[pos++].value = c[i][j];
++arr[0].value;
}
if (arr[0].row == 1)
++arr[0].col;
}
}
return;
}
void transPose(term* arr, term* brr)//将a转置到b中储存
{
int row_nums = arr[0].row;
int col_nums = arr[0].col;
int num_terms = arr[0].value;
int brow_terms[col_nums];
int pos[col_nums]; //用pos数组储存每次转置时存放到b中元素应放的下标
brr[0].row = arr[0].col;
brr[0].col = arr[0].row;
brr[0].value = num_terms;
if (num_terms > 0)
{
for (int i = 0; i < col_nums; ++i)//首先初始化b中每行元素的个数为0
{
brow_terms[i] = 0;
}
for (int i = 1; i <= num_terms; ++i)//计算b中每行元素个数,即a中每列元素的个数
{
++brow_terms[arr[i].col];
}
pos[0] = 1;
for (int i = 1; i < col_nums; ++i)//计算每行开始转存时元素 的下标
{
pos[i] = pos[i-1] + brow_terms[i-1];
}
int j;
for (int i = 1; i <= num_terms; ++i)//将a中的元素转存到b中
{
j = pos[arr[i].col]++;
brr[j].row = arr[i].col;
brr[j].col = arr[i].row;
brr[j].value = arr[i].value;
}
return;
}
}
void printArray(term* arr)//打印输出查看效果
{
int num_terms = arr[0].value;
printf("this one:\n");
for (int i = 1; i <= num_terms; ++i)
{
printf("(%d,%d):%d\n",arr[i].row,arr[i].col,arr[i].value);
}
return;
}
int main()
{
term a[MAX_TERMS];
term b[MAX_TERMS];
int source[10][10];
initSparseMatrix(source);
saveMatrixIntoArray(a,source);
transPose(a,b);
printArray(a);
printArray(b);
return 0;
}