您的位置:首页 > 其它

稀疏矩阵的压缩存储

2017-05-09 18:12 302 查看
#include <vector>
#include <iostream>
using namespace std;
template<class T>
class SparseMatrix
{
public:
// 稀疏矩阵的压缩存储
SparseMatrix(int* array, size_t row, 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)
{
Trituple<T> a(i, j, array[i*col + j]);
_sm.push_back(a);
}
}
}
}

SparseMatrix()
{}

// 访问稀疏矩阵中row行col中的元素
T& Access(int row, int col)
{
////遍历数组两种方法
////1.for循环
////2.迭代器
//vector<Trituple<T>>::iterator it = _sm.begin();

//while (it != _sm.end())
//{
//	if (it->_row == row&&it->_col == col)
//	{
//		return it->_data;
//	}
//	it++;
//}
//return _invalid;
for (size_t i = 0; i < _sm.size(); ++i)
{
if (_sm[i]._row == row&&_sm[i]._col == col)
{
return _sm[i]._data;
}
return _invalid;
}
}

// 还原稀疏矩阵
template<class T>
friend ostream& operator<<(ostream& _cout, SparseMatrix<T>& s)//要申明为友元函数
{
int index = 0;
for (size_t i = 0; i < s._row; ++i)
{
for (size_t j = 0; j < s._col; ++j)
{
if (index<s._sm.size() && i == s._sm[index]._row&&j == s._sm[index]._col)
{
_cout << s._sm[index++]._data << " ";
}
else
{
_cout << s._invalid << " ";
}
}
_cout << endl;
}
return _cout;
}

// 实现稀疏矩阵的逆置,并给出时间复杂度
//直接存储是有问题的,打印是按照行优先打印存储也要行优先存储
SparseMatrix<T> Transprot()
{
SparseMatrix<T> sm;//定义一个逆转后的结构体
sm._col = _row;
sm._row = _col;
sm._invalid = _invalid;
/*使用迭代器*/
//for (int i = 0; i < _col; ++i)
//{
//	vector<Trituple<T>>::iterator it = _sm.begin();
//	while (it != _sm.end())
//	{
//		if (i == it->_col)
//		{
//			sm._sm.push_back(Trituple<T>(it->_col, it->_row, it->_data));
//		}
//		it++;

//	}
//}
//return sm;
//时间复杂度O(M*N)
for (size_t i = 0; i < _col; ++i)
{
size_t index = 0;
while (index < _sm.size())
{
if (_sm[index]._col == i)
{
//三元组tmp存入满足下表i的元素
Trituple<T> tmp(_sm[index]._col, _sm[index]._row, _sm[index]._data);
sm._sm.push_back(tmp);
}
++index;//此处要++index而不是index++
}

}
return sm;
}

// 实现稀疏矩阵的快速逆置,并给出时间复杂度
SparseMatrix<T> FastTransprot()
{
SparseMatrix<T> sm;//定义一个逆转后的结构体
sm._col = _row;
sm._row = _col;
sm._invalid = _invalid;
sm._sm.reserve(_sm.size());//开辟有效元素个空间

//1、统计原矩阵中每一列有多少个有效元素
int* pCount = new int[_col];
memset(pCount, 0, _col*sizeof(pCount[0]));
for (int i = 1; i < _sm.size(); ++i)
{
pCount[_sm[i]._col]++;
}

//2、原矩阵的每一列在新矩阵中的起始位置
int* pAddr = new int[_col];
memset(pAddr, 0, _col*sizeof(pAddr[0]));
for (int j = 1; j < _col; ++j)
{
pAddr[j] = pAddr[j - 1] + pCount[j - 1];
}
//3、放置元素到新的空间
for (int i = 0; i < _sm.size(); ++i)
{
//Trituple<T> t(_sm[i]._col, _sm[i]._row, _sm[i]._data);
//sm._sm[pAddr[_sm[i]._col]] = t;
//pAddr[_sm[i]._col] ++;
int & addr = pAddr[_sm[i]._col];
sm._sm[addr] = Trituple<T>(_sm[i]._col, _sm[i]._row, _sm[i]._data);
addr++;
}

return sm;
}

//	// 实现稀疏矩阵的加法操作
//SparseMatrix<T> operator+(const SparseMatrix<T>& sp);

//三元组
template<class T>
struct Trituple
{
Trituple(size_t row, size_t col, const T& data)
: _row(row)
, _col(col)
, _data(data)
{}

Trituple()//无参数构造函数
{}

size_t _row;
size_t _col;
T _data;
};
private:
vector<Trituple<T>> _sm;
size_t _row;
size_t _col;
T _invalid;
};
void TestSparseMatrix()
{
int array[6][5] =
{
{ 1, 0, 3, 0, 5 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0 },
{ 2, 0, 4, 0, 6 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0 } };
SparseMatrix<int> sp((int*)array, sizeof(array) / sizeof(array[0]), sizeof(array[0]) / sizeof(array[0][0]), 0);

cout << sp << endl;
cout << endl;

SparseMatrix<int> sp1 = sp.Transprot();

cout << sp1 << endl;

SparseMatrix<int> sp2 = sp.FastTransprot();

cout << sp2 << endl;
}
int main()
{
TestSparseMatrix();
system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: