稀疏矩阵快速转置算法理解

稀疏矩阵:绝大多数元素为零的矩阵。

稀疏矩阵的压缩储存:只储存稀疏矩阵中的非零元素,用三元式(row,col,value)唯一表示每一个非零元素的行号、列号和值,按行\列顺序以一维数组的形式储存形成行\列三元组。

快速转置算法的基本步骤:1. 计算每列非零元素个数,存入num[ ]中;

                                            2. 计算每列第一个非零元素在新的行三元组中的位置,存入k[ ]中;

                                            3. 快速转置。

 用以下矩阵为例: (红色下标表示该元素在三元组中的位置)

转置前:                                                                                                                                                         

    稀疏矩阵快速转置算法理解_第1张图片                稀疏矩阵快速转置算法理解_第2张图片

转置后:

 稀疏矩阵快速转置算法理解_第3张图片     稀疏矩阵快速转置算法理解_第4张图片

num数组:                         

0 1 2 3 4 5
2 1 2 2 0 1

num数组与k数组的关系: k[0]=0

                                             k[i]=k[i-1]+num[i-1]   (1<=i

                                          

由此得k数组:

0 1 2 3 4 5
0 2 3 5 7 7

代码如下:

//说明:m为行数,n为列数,t为非零元素的个数
template
void SeqTriple::Transpose(SeqTriple& B) const	//将转置后的矩阵赋给B
{
	int *num=new int[n];	//为num和k数组分配空间
	int *k=new int [n];
	B.m=n;
	B.n=m;
	B.t=t;
	if(t>0)
	{
		for(int i=0; i

程序运行模拟:

1. j=k[0]=0,k[0]++后=1          2. j=k[3]=5,k[3]++后=6             3. j=k[5]=7,k[5]++后=8  

稀疏矩阵快速转置算法理解_第5张图片         稀疏矩阵快速转置算法理解_第6张图片                  稀疏矩阵快速转置算法理解_第7张图片


4. j=k[1]=2,k[1]++后=3          5. j=k[2]=3,k[2]++后=4             6. j=k[3]=6,k[3]++后=7

稀疏矩阵快速转置算法理解_第8张图片          稀疏矩阵快速转置算法理解_第9张图片              稀疏矩阵快速转置算法理解_第10张图片

       


 7. j=k[0]=1,k[0]++后=2          8. j=k[2]=4,k[2]++后=5

稀疏矩阵快速转置算法理解_第11张图片         稀疏矩阵快速转置算法理解_第12张图片 


算法分析:快速转置算法的时间复杂度为O(n+t),空间上增加了2个一维数组num和k。

算法优化:可以省去num数组,即不通过num数组计算出k数组的值。

方法一:将k数组初始化为0,扫描一遍行三元组,每次就从对应的k[col+1]开始,把往后的所有k值加1。如,第一遍扫到的是0 0 16,col=0,则k[1]到k[5]的值都要加一。亲测有效。

方法二:先把k数组当作num数组用,这时k数组的值应为2 1 2 2 0 1,然后借助两个 临时变量tmp1,tmp2,分别保存上一个k的初值和当前k的初值,注意k[0]=0,计算k的公式为:k[i]=tmp1+k[i-1],即当前的k值等于上一个k的初值加上更新了的k值。可以这么理解,因为k保存的是每一列第一个非零元素在新三元组的位置,所以当前列第一个非零元素的位置就等于上一列非零元素的个数(tmp1)+上一列第一个非零元素的位置(k[i-1])。

代码如下,可供参考:

	int tmp1,tmp2;
	tmp1=k[0];
	k[0]=0;
	for(int i=1; i



你可能感兴趣的:(算法学习)