稀疏矩阵的转置和快速转置

来源:互联网 发布:视频软件哪个好 编辑:程序博客网 时间:2024/04/28 22:42

稀疏矩阵压缩存储:

代码:

#pragma once#include<vector>using namespace std;template<class T>struct Triple{Triple(){}Triple(T & v, int r, int c):_value(v), _row(r), _col(c){}size_t _row;size_t _col;T _value;};//稀疏矩阵的压缩存储  template<class T>class SparseMatrix{public:SparseMatrix():_RowSize(0), _ColSize(0){}SparseMatrix(T * a, size_t row, size_t col,const T & invalid):_RowSize(row), _ColSize(col), _invalid(invalid){for (size_t i = 0; i < _RowSize; ++i){for (size_t j = 0; j < _ColSize; j++){if (a[i*_ColSize + j] != invalid){Triple<T> t(a[i*_ColSize + j], i, j);_array.push_back(t);}}}}void Display(){size_t index = 0;for (size_t i = 0; i < _RowSize; ++i){for (size_t j = 0; j < _ColSize; j++){if (index<_array.size()&&_array[index]._row==i &&_array[index]._col==j ){cout << _array[index++]._value << " ";}else{cout << _invalid<<" ";}}cout << endl;}cout << endl;}private:vector<Triple<T>> _array;size_t _RowSize;size_t _ColSize;T _invalid;  //非法值};
//转置算法为成员函数,在下面列出


一般转置算法:从保存矩阵的数组中抽取列为index的元素,转换行列值后,插入到新的矩阵中,经过列数col次迭代,即可完成转置。

完整代码如下:


SparseMatrix<T> Transpose()  //转置{SparseMatrix sm;sm._RowSize = _ColSize;sm._ColSize = _RowSize;sm._invalid = _invalid;int i=0;for (int j = 0; j < _ColSize; ++j){i = 0;while ( i < _array.size()){if (j == _array[i]._col){Triple<T> t(_array[i]._value, _array[i]._col, _array[i]._row);sm._array.push_back(t);}++i;}}return sm;//O(有效元素数*列数)}
<pre name="code" class="cpp">



快速转置算法:经过常数次运算,求出转置后,每行的起始位置,之后遍历一次存储矩阵的数组进行迭代插入,这样可以在O(n)的时间复杂度下完成转置。


SparseMatrix<T> Transpose()  //转置{SparseMatrix sm;sm._RowSize = _ColSize;sm._ColSize = _RowSize;sm._invalid = _invalid;int i=0;for (int j = 0; j < _ColSize; ++j){i = 0;while ( i < _array.size()){if (j == _array[i]._col){Triple<T> t(_array[i]._value, _array[i]._col, _array[i]._row);sm._array.push_back(t);}++i;}}return sm;//O(有效元素数*列数)}SparseMatrix<T> FastTranspose()   //快速转置{SparseMatrix sm;sm._ColSize = _RowSize;sm._RowSize = _ColSize;sm._invalid = _invalid;sm._array.resize(_array.size());  //这块会调用默认构造函数 所以Triple必须默认构造函数int index = 0;int* RowCount = new int[_ColSize];int* RowStart = new int[_ColSize];memset(RowCount, 0, sizeof(int)*_ColSize);memset(RowStart, 0, sizeof(int)*_ColSize);while (index < _array.size())  //一次迭代O(n){++RowCount[_array[index++]._col];}index = 1;while (index < _ColSize)      //O(n){RowStart[index] = RowStart[index - 1] + RowCount[index - 1];++index;}//执行快速转置int i = 0;while (i < _array.size())  //两次迭代 O(n){Triple<T>  t(_array[i]._value, _array[i]._col, _array[i]._row);sm._array[RowStart[_array[i]._col]++] = t;++i;}delete[] RowCount;delete[] RowStart;return sm;//时间复杂度O(有效元素数*常数次迭代)}



0 0
原创粉丝点击