稀疏矩阵的压缩存储

29 篇文章 0 订阅
20 篇文章 0 订阅
#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;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值