设一个N*N的矩阵A,A中任意元素Aij,当且仅当Aij==Aji(0 <= i <= N-1 && 0 <=j <= N-1),则矩阵A是对称矩阵。以矩阵的对角线为分割,分为上三角和下三角。
如图所示:
对称矩阵压缩存储:
压缩矩阵:对称矩阵存储时只需要存储上三角或下三角的数据,所以最多存储n*(n+1)/2个数据。
对称矩阵和对称压缩存储的对应关系:
下三角存储i>=j,SymmetricMatrix[i][j] == Array[i*(i+1)/2+j]
下面附上代码,部分注释已在代码中给出:
#include <iostream>
#include<vector>
using namespace std;
//实现对称矩阵的压缩存储
template<class T>
class SymmetricMatrix
{
public:
SymmetricMatrix(const T* array, size_t N)
:_row(N)
, _col(N)
{
_size = (N*(N + 1)) >> 1;
_pData = new T[_size];
size_t idx = 0;
for (int i = 0; i<N; ++i)
{
for (int j = 0; j <= i; ++j)
{
_pData[idx++] = array[i*N + j];
}
}
}
const T& Access(int row, int col)const
{
if (row<col)
swap(row, col);
return _pData[(row*(row + 1)) >> 1 + col];
}
T& Access(int row, int col)
{
if (row<col)
swap(row, col);
return _pData[(row*(row + 1) >> 1) + col];
}
~SymmetricMatrix()
{
if (_pData)
{
delete[] _pData;
_pData = NULL;
_size = 0;
}
}
template<class T>
friend ostream& operator<<(ostream& _cout, SymmetricMatrix<T>& sm)
{
for (size_t i = 0; i<sm._row; ++i)
{
for (size_t j = 0; j<sm._col; ++j)
{
_cout << sm.Access(i, j) << " ";
}
_cout << endl;
}
return _cout;
}
void PrintMatrix()
{
for (size_t i = 0; i<_row; ++i)
{
for (size_t j = 0; j<_col; ++j)
{
cout << Access(i, j) << " ";
}
cout << endl;
}
}
private:
T* _pData;
size_t _size;
size_t _col;
size_t _row;
};
int main()
{
int a[5][5] =
{
{ 0, 1, 2, 3, 4 },
{ 1, 0, 1, 2, 3 },
{ 2, 1, 0, 1, 2 },
{ 3, 2, 1, 0, 1 },
{ 4, 3, 2, 1, 0 }
};
SymmetricMatrix<int> sm((int*)a, 5);
cout << sm.Access(2, 4) << endl;
cout << sm << endl;
sm.PrintMatrix();
system("pause");
return 0;
}
结果如图: