稀疏矩阵的快速转置

来源:互联网 发布:仁化长江镇县网络问政 编辑:程序博客网 时间:2024/04/28 00:19

一般的稀疏矩阵转置算法

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 101typedef 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;elsec[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;} 


简单来说,相比于第一个转置算法,快速转置的提升在于不用检索a中的每一个元素查找位于当前列的元素,并将其放置到b中。利用pos数组储存了b中每一行对应的起始下标,从而能够直接讲元素加入到b中。
0 0
原创粉丝点击