稀疏矩阵的转置和快速转置

稀疏矩阵压缩存储:

代码:

#pragma once

#include<vector>
using namespace std;

template<class T>
struct Triple
{
	Triple()
	{}
	Triple(T & v, int r, int c)
	:_value(v)
	, _row(r)
	, _col(c)
	{}
	size_t _row;
	size_t _col;
	T _value;
};

//稀疏矩阵的压缩存储  
template<class T>
class SparseMatrix
{
public:
	SparseMatrix()
		:_RowSize(0)
		, _ColSize(0)
	{
	}
	SparseMatrix(T * a, size_t row, size_t col,const T & invalid)
		:_RowSize(row)
		, _ColSize(col)
		, _invalid(invalid)
	{
		for (size_t i = 0; i < _RowSize; ++i)
		{
			for (size_t j = 0; j < _ColSize; j++)
			{
				if (a[i*_ColSize + j] != invalid)
				{
					Triple<T> t(a[i*_ColSize + j], i, j);
					_array.push_back(t);
				}
			}
		}
	}

	void Display()
	{
		size_t index = 0;
		for (size_t i = 0; i < _RowSize; ++i)
		{
			for (size_t j = 0; j < _ColSize; j++)
			{
				if (index<_array.size()&&_array[index]._row==i &&_array[index]._col==j )
				{
					cout << _array[index++]._value << " ";
				}
				else
				{
					cout << _invalid<<" ";
				}
			}
			cout << endl;
		}
		cout << endl;
	}
private:
	vector<Triple<T>> _array;
	size_t _RowSize;
	size_t _ColSize;
	T _invalid;  //非法值
};
//转置算法为成员函数,在下面列出


一般转置算法:从保存矩阵的数组中抽取列为index的元素,转换行列值后,插入到新的矩阵中,经过列数col次迭代,即可完成转置。

完整代码如下:


SparseMatrix<T> Transpose()  //转置
	{
		SparseMatrix sm;
		sm._RowSize = _ColSize;
		sm._ColSize = _RowSize;
		sm._invalid = _invalid;
		int i=0;
		for (int j = 0; j < _ColSize; ++j)
		{
			i = 0;
			while ( i < _array.size())
			{
				if (j == _array[i]._col)
				{
					Triple<T> t(_array[i]._value, _array[i]._col, _array[i]._row);
					sm._array.push_back(t);
				}
				++i;
			}
		}
		return sm;
		//O(有效元素数*列数)
	}
<pre name="code" class="cpp">

 


快速转置算法:经过常数次运算,求出转置后,每行的起始位置,之后遍历一次存储矩阵的数组进行迭代插入,这样可以在O(n)的时间复杂度下完成转置。


SparseMatrix<T> Transpose()  //转置
	{
		SparseMatrix sm;
		sm._RowSize = _ColSize;
		sm._ColSize = _RowSize;
		sm._invalid = _invalid;
		int i=0;
		for (int j = 0; j < _ColSize; ++j)
		{
			i = 0;
			while ( i < _array.size())
			{
				if (j == _array[i]._col)
				{
					Triple<T> t(_array[i]._value, _array[i]._col, _array[i]._row);
					sm._array.push_back(t);
				}
				++i;
			}
		}
		return sm;
		//O(有效元素数*列数)
	}

	
	SparseMatrix<T> FastTranspose()   //快速转置
	{
		SparseMatrix sm;
		sm._ColSize = _RowSize;
		sm._RowSize = _ColSize;
		sm._invalid = _invalid;
		sm._array.resize(_array.size());  //这块会调用默认构造函数 所以Triple必须默认构造函数
		int index = 0;
		int* RowCount = new int[_ColSize];
		int* RowStart = new int[_ColSize];
		memset(RowCount, 0, sizeof(int)*_ColSize);
		memset(RowStart, 0, sizeof(int)*_ColSize);



		while (index < _array.size())  //一次迭代O(n)
		{
				++RowCount[_array[index++]._col];
		}
		index = 1;
		while (index < _ColSize)      //O(n)
		{
			RowStart[index] = RowStart[index - 1] + RowCount[index - 1];
			++index;
		}

		//执行快速转置
		int i = 0;
		while (i < _array.size())  //两次迭代 O(n)
		{
			
			Triple<T>  t(_array[i]._value, _array[i]._col, _array[i]._row);
			sm._array[RowStart[_array[i]._col]++] = t;
			++i;
		}



		delete[] RowCount;
		delete[] RowStart;

		return sm;

		//时间复杂度O(有效元素数*常数次迭代)
	}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值