稀疏矩阵的压缩存储及转置算法

原创 2016年05月30日 13:35:33

矩阵(Matrix)是一个按照长方阵列排列的复数实数集合.

稀疏矩阵:有效数据远少于无效数据。

 eg:规定无效数据为 0 

    1 0 0 0 0

    0 0 0 0 2

    0 3 0 0 0

    4 0 0 0 0

上述矩阵则可称为一个稀疏矩阵

我们在学习C语言的时候已经见过并使用过矩阵,其实它在我们的编程语言里可以翻译成二维数组,由于稀疏矩阵的有效数据十分的少,完全存储十分耗费我们的空间,所以我们选择只存储它的有效数据位,所以我们可以直接使用一维数组将其存储起来,但是我们必须让别人在看它时还能知道它是一个矩阵,于是我们必须将其所在的位置使用一个三元组存储起来!

三元组的定义如下:

template<class T>
struct Triple
{
	T _value;//有效值
	int _row;//该值所在行
	int _col;//该值所在列
	Triple(const T& data = T(), int m = 0, int n = 0)
	       :_value(data),_row(m), _col(n)
	{}
};


矩阵的定义如下:

class SpaMatrix
{
public:
	SpaMatrix(T* arr = NULL, int m = 0, int n = 0, int inva = 0)
		:_Row(m), _Col(n), _invalid(inva)
	{
		int index = 0;
		for (int i = 0; i < m; i++)
		{
			for (int j = 0; j < n; j++)
			{
				if (arr[i*n + j] != _invalid)
				{
					_a.push_back(Triple<T>(arr[i*n + j], i, j));
					_n ++;
				}
			}
		}
	}
private:
	vector< Triple<T> > _a;//存储三元组
	int _invalid;//规定的无效值
	int _Row;//矩阵的行数
	int _Col;//矩阵的列数
};


在矩阵里,我们经常能够看见一个运算,就是矩阵的转置,即使得a[i][j] = a[j][i],我们之前在存储矩阵时选择了行优先的存储方式,但是,转置之后,我们的矩阵是以原来的行为它的列,我们该如何做呢?

方法一:普通转置

**我们遍历矩阵,将第一列数据先放入新的矩阵,再放第二列,第三列,以此类推,这样,我们就能够得到新的矩阵

下面是代码的实例(截取重要部分代码):

	//普通转置
	SpaMatrix<T>::SpaMatrix<T> OrdinaryTrans()
	{
		int count = 0;
		int index = 0;
		SpaMatrix<T> sp;//使用一个临时变量存储转置后的矩阵
		
			for (int j = 0; j < _Col; j++)
			{ 
				for (int index = 0; index < _a.size(); index++)
				{
					if (_a[index]._col == j)
					{
					    //每次只push需要的列
						sp._a.push_back(_a[index]);
						sp._a[index]._row = _a[index]._col;
						sp._a[index]._col = _a[index]._row;
					}
				}
			}
			//更新转置后的矩阵行列信息
			sp._Row = _Col;
			sp._Col = _Row;
			
		return sp;
	}


方法二:快速转置

**我们将原来的矩阵的每一列有效数据的起始位和每一列有效数据的个数保存起来,作为新矩阵的每一行有效数据的起始位置和有效数据个数,当我们想要的得到某个数据时,使用 上一行的起始位置+有效数据的个数即可得到我们新的矩阵。

我们来看看代码的实例:

	//快速转置
	SpaMatrix<T>::SpaMatrix<T> FastTrans()
	{
		//统计有效数据的开始位置
		int *RowStart = new int[_Col];
		//统计转置之后的矩阵里每行的有效数据的个数
		int *RowCount = new int[_Col];
		memset(RowCount, 0, sizeof(int)*_Col);
		memset(RowStart, 0, sizeof(int)*_Col);
		size_t index = 0;

		//Set RowCount
		while (index < _a.size())
		{
			RowCount[_a[index]._col]++;
			index++;
		}
				
		//Set RowStart
		RowStart[0] = 0;
		for (int i = 1; i < _Col; i++)
		{
			RowStart[i] = RowStart[i - 1] + RowCount[i - 1];
		}

		//构造转置之后的矩阵
		SpaMatrix<T> sptrans;
		sptrans._Row = _Col;
		sptrans._Col = _Row;
		sptrans._n = _n;
		
		//index 值已经改变了,必须重新让其等于0
		index = 0;

		//此处使用下标访问必须开辟空间,但如果使用push_back()可以不用开辟~
		sptrans._a.resize(_a.size());
	        while(index < _a.size())
		{
			int Rowindex = _a[index]._col;
			//此处注意引用
			int& RowSt = RowStart[Rowindex];

			sptrans._a[RowSt]._value = _a[index]._value;
			sptrans._a[RowSt]._col = _a[index]._row;
			sptrans._a[RowSt]._row = _a[index]._col;

			index++;
			//每次必须更新该位置,否则错误
			RowSt++;
		}
		return sptrans;
	}

以上是我自己实现的转置代码,虽然代码渣,但是就是有迷之自信敢给你们看,我就问你们怕不怕B_0037.gif

本文出自 “Zimomo” 博客,请务必保留此出处http://zimomo.blog.51cto.com/10799874/1764814

版权声明:本文为博主原创文章,未经博主允许不得转载。

【数据结构】稀疏矩阵的压缩存储和转置算法(C++代码)

稀疏矩阵的压缩存储和转置算法
  • u010834867
  • u010834867
  • 2017年04月06日 15:59
  • 1263

稀疏矩阵-压缩存储-列转置法- 一次定位快速转置法

稀疏矩阵的压缩存储压缩存储值存储极少数的有效数据。使用{row,col,value}三元组存储每一个有效数据,三元组按原矩阵中的位置,以行优先级先后顺序依次存放。650) this.width=650...
  • alick97
  • alick97
  • 2016年10月25日 14:01
  • 667

5.3矩阵的压缩存储(稀疏矩阵转置和快速转置)

5.3矩阵的压缩存储(稀疏矩阵转置和快速转置)
  • qq78442761
  • qq78442761
  • 2017年02月09日 15:22
  • 2950

稀疏矩阵的快速转置和乘法运算源代码(非常详细)

/*sparseMatrix.h*/ #include "stdio.h" #include "stdlib.h" #define SIZE 100 typedef struct { in...
  • serena_0916
  • serena_0916
  • 2017年11月29日 08:20
  • 238

【LB】稀疏矩阵的快速转置原理及其算法

关于稀疏矩阵的快速转置法,首先得明白其是通过对三元表进行转置。如果误以为是对矩阵进行转置,毫无疑问就算你想破脑袋也想不出个所以然,别陷入死胡同了!          对于一个三元表,行为i,列为...
  • u013598542
  • u013598542
  • 2014年04月14日 22:30
  • 7401

稀疏矩阵压缩存储

通常在高级语言编程中,都是用二维数组来存储矩阵的元,然而在阶数很高的矩阵中,有很多值相同的元或者是零元素。有时为了节省存储空间,可以对这类矩阵进行压缩存储。所谓压缩存储是指:为多个值相同的元只分配一个...
  • taohuaxinmu123
  • taohuaxinmu123
  • 2014年03月07日 11:04
  • 6776

稀疏矩阵的普通转置与快速转置算法

稀疏矩阵的普通转置与快速转置算法 一般来说,对于系数矩阵,我们使用三元组来存储。即就是将矩阵的所有非零元素的三元组存放在一个顺序表中,如图所示: 注意一个转置的前提:该顺序表是排好序的,即行优...
  • qq845579063
  • qq845579063
  • 2016年05月09日 17:49
  • 3407

C++实现矩阵压缩存储与(快速)转置

注意:以下所有代码均在VS2010环境下运行测试             了解了C语言以后,我们都知道,要存储一个矩阵,用一个二维数组即可实现,今天,由我来带领大家玩点新鲜的,对矩阵进行压缩存储并对其...
  • snow_5288
  • snow_5288
  • 2016年12月10日 19:05
  • 7853

稀疏矩阵的存储方式及其快速转置的实现

稀疏矩阵: M*N的矩阵,矩阵中有效值的个数远小于无效值的个数,且这些数据的分布没有规律。 如下图矩阵: 稀疏矩阵的压缩存储方式: 压缩存储极少数的有效数据。使用{row,col,value}...
  • xyzbaihaiping
  • xyzbaihaiping
  • 2016年04月19日 14:52
  • 1920

稀疏矩阵的快速转置算法

稀疏矩阵的快速转置算法在描述稀疏矩阵的快速转置算法之前,先了解什么是稀疏矩阵和什么是稀疏矩阵的压缩存储;稀疏矩阵的压缩存储什么是稀疏矩阵? /* 这是大学的以么课《线性代数》学的,不知道大家还记得多少...
  • bitboss
  • bitboss
  • 2016年09月28日 09:09
  • 3908
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:稀疏矩阵的压缩存储及转置算法
举报原因:
原因补充:

(最多只允许输入30个字)