稀疏矩阵的特点:零元多,非零元远少于零元,存储数据没什么规律
因此可以采用只存储非零元素的方法来进行压缩存储(为了节省空间)。所以在进行压缩存储的时侯需要存储非零元素值的同时还要存储非零元素在矩阵中的位置,即非零元素所在的行号和列号,也就是在存储某个元素比如aij的值的同时,还需要存储该元素所在的行号i和它的列号j,这样就构成了一个三元组(row,col,value)的线性表。
也可以用链表实现,我这里用的是线性表
#include<iostream>
#include<vector>
using namespace std;
//稀疏矩阵的压缩存储及转置
template<class T>
struct Triple
{
int _row;
int _col;
T _value;
Triple (const T& value = T(),
int row = 0, int col = 0)
:_value(value)
,_row(row)
,_col(col)
{
}
};
template<class T>
class coefficient_matrix
{
public :
coefficient_matrix()
:_colsize(0)
,_rowsize(0)
{}
//二维数组入顺序表
coefficient_matrix(int* a,int row,int col,const int invalid )
:_rowsize (row)
,_colsize (col)
,_invalid (invalid )
{
for( int i = 0;i < row ; i++)
{
for(int j = 0;j <col ; j++)
{
//压缩存储,只存储有效值
if(a[col*i+j]!= invalid )
{
_a.push_back(Triple<T>(a[col*i+j],i,j));//将二维数组的有效值 尾插入 顺序表:有行,有列,有值
}
}
}
}
void Display()
{
size_t index = 0;
for(int i= 0;i<_rowsize ;i++)
{
for(int j= 0;j<_colsize ;j++)
{
if((index < _a.size ())&&(_a[index]._row == i)&&(_a[index]._col == j))
{
cout <<_a[index]._value<<" ";
index++;
}
else
{
cout<<_invalid <<" ";
}
}
cout<<endl;
}
cout<<endl;
}
//普通转置 (时间复杂度: o(colSize*有效数据的个数))
//coefficient_matrix<T> transport()
//{
// coefficient_matrix<T> tmp;
// tmp._colsize = _rowsize ;
// tmp._rowsize = _colsize ;
// tmp._invalid = _invalid ;
// for(int i = 0; i< _colsize ;i++)
// {
// int index = 0;
// while(index < _a.size ())
// {
// if(_a[index ]._col==i)
// {
// Triple<T> t;
// t._col = _a[index ]._row;
// t._row = _a[index ]._col;
// t._value =_a[index ]._value;
// tmp._a.push_back (t);
// }
// index++;
// }
// }
// return tmp;
//}
//快速转置
coefficient_matrix<T> FastTransport()
{
coefficient_matrix<T> tmp;
tmp._colsize = _rowsize;
tmp._rowsize = _colsize;
tmp._invalid = _invalid;
int* rowCounts = new int[_colsize];
int* rowStart = new int[_colsize];
memset(rowCounts, 0, sizeof(int)*_colsize);
memset(rowStart, 0, sizeof(int)*_colsize);
int index = 0;
while (index < _a.size())
{
rowCounts[_a[index]._col]++;
++index;
}
rowStart[0] = 0;
for (size_t i = 1; i < _colsize; ++i)
{
rowStart[i] = rowStart[i-1] + rowCounts[i-1];
}
index = 0;
//tmp._a.reserve(_a.size());
tmp._a.resize(_a.size());
while (index < _a.size())
{
size_t rowIndex = _a[index]._col;
int& start = rowStart[rowIndex];
Triple<T> t;
t._value = _a[index]._value;
t._row = _a[index]._col;
t._col = _a[index]._row;
tmp._a[start++] = t;
++index;
/*tmp._a[(rowStart[_a[index]._col])++] =
Triple<T>(_a[index]._value, _a[index]._col, _a[index]._row);*/
}
return tmp;
}
protected:
vector<Triple<T>> _a;//结构体类型顺序表,三元组:位置,value
int _rowsize;
int _colsize;
T _invalid;
};
int main()
{
int arr[][4]=
{
{0,0,1,0},
{0,2,0,0},
{3,0,0,0}
//{1, 0, 3, 0},
//{0, 0, 0, 0},
//{0, 0, 0, 0},
//{2, 0, 4, 0},
//{0, 0, 0, 0},
//{0, 0, 0, 0}
};
coefficient_matrix<int> cm1((int*)arr,3,4,0);
cm1.Display ();
coefficient_matrix<int> cm2=cm1.FastTransport ();
cm2.Display ();
return 0;
}