对称矩阵及对称矩阵的压缩存储
设一个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]
稀疏矩阵
M*N的矩阵,矩阵中有效值的个数远小于无效值的个数,且这些数据的分布没 有规律。
稀疏矩阵的压缩存储
压缩存储值存储极少数的有效数据。使用{row,col,value}三元组存储每一个有效 数据,三元组按原矩阵中的位置,以行优先级先后顺序依次存放。
将原矩阵的行、列对换,也就是将[i][j]和[j][i]位置上的数据对换。
template<typename T>
class SpareMatric
{
typedef ThirdArray<T> ThirdArray;
public:
SpareMatric(T* array,const size_t& row,const size_t& col,const T& invalid)
:_row(row)
, _col(col)
, _invalid(invalid)
{
for (size_t i = 0; i < row; i++)
{
for (size_t j = 0; j < col; j++)
{
if (array[i*col + j] != invalid)
{
_array.push_back(ThirdArray(i, j, array[i*col + j]));
}
}
}
}
void Display()
{
size_t index = 0;
for (size_t i = 0; i < _row; i++)
{
for (size_t j = 0; j < _col; j++)
{
if (index < _array.size() && _array[index]._x==i&&_array[index]._y==j)
{
cout << _array[index]._value << " ";
index++;
}
else
{
cout << _invalid<< " ";
}
}
cout << endl;
}
}
vector<ThirdArray> _array;
size_t _row;
size_t _col;
T _invalid;
};
快速转置
矩阵的加法&乘法–斐波那契数列
稀疏矩阵的快速转置
#pragma once
#include<iostream>
#include<vector>
using namespace std;
template<typename T>
struct ThirdArray
{
size_t _x;
size_t _y;
T _value;
ThirdArray(const size_t& row=0, const size_t& col=0, const T& value=T())
:_x(row)
, _y(col)
, _value(value)
{}
};
template<typename T>
class SpareMatric
{
typedef ThirdArray<T> ThirdArray;
public:
SpareMatric(T* array,const size_t& row,const size_t& col,const T& invalid)
:_row(row)
, _col(col)
, _invalid(invalid)
{
for (size_t i = 0; i < row; i++)
{
for (size_t j = 0; j < col; j++)
{
if (array[i*col + j] != invalid)
{
_array.push_back(ThirdArray(i, j, array[i*col + j]));
}
}
}
}
void Display()
{
size_t index = 0;
for (size_t i = 0; i < _row; i++)
{
for (size_t j = 0; j < _col; j++)
{
if (index < _array.size() && _array[index]._x==i&&_array[index]._y==j)
{
cout << _array[index]._value << " ";
index++;
}
else
{
cout << _invalid<< " ";
}
}
cout << endl;
}
}
vector<ThirdArray> _array;
size_t _row;
size_t _col;
T _invalid;
};
template<typename T>
class TransposeMatric
{
typedef ThirdArray<T> ThirdArray;
public:
TransposeMatric(SpareMatric<T>& Matric)
:_row(Matric._col)
, _col(Matric._row)
, _invalid(Matric._invalid)
{
_Trans.resize(Matric._array.size());
vector<size_t> num;
vector<size_t> cpot;
num.resize(Matric._col);
cpot.resize(Matric._col);
for (size_t i = 0; i < Matric._array.size(); i++)
{
num[Matric._array[i]._y]++;
}
cpot[0] =0;
for (size_t i = 1; i < Matric._col; i++)
{
cpot[i] = cpot[i - 1] + num[i-1];
}
for (size_t i = 0; i<_Trans.size(); i++)
{
size_t col = Matric._array[i]._y;
size_t pos = cpot[col];
_Trans[pos]._x= Matric._array[i]._y;
_Trans[pos]._y= Matric._array[i]._x;
_Trans[pos]._value= Matric._array[i]._value;
++cpot[col];
}
}
void Display()
{
size_t index = 0;
for (size_t i = 0; i < _row; i++)
{
for (size_t j = 0; j < _col; j++)
{
if (index < _Trans.size() && _Trans[index]._x == i&&_Trans[index]._y == j)
{
cout << _Trans[index]._value << " ";
index++;
}
else
{
cout << _invalid << " ";
}
}
cout << endl;
}
}
protected:
vector<ThirdArray> _Trans;
size_t _row;
size_t _col;
T _invalid;
};