稀疏矩阵的快速转制

本文介绍了两种稀疏矩阵转置算法,一种是基础版本,另一种是改进版本,后者通过额外使用数组提高了运行效率,降低了时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

学习的过程中遇到的稀疏矩阵的快速转制的一个小结,贴在这里。

1.稀疏矩阵?http://baike.baidu.com/view/891721.htm 百度百科的链接。

2.稀疏矩阵的存储和数据结构的具体代码如下:

  用三元组的形式存储稀疏矩阵:每个元素的描述需要三方面的信息,(1)所在列col;(2)所在行row;(3)值value

 

typedef struct{
	int col;
	int row;
	int value;
}term;

注:对于每个定义的term数组,第一个数组元素的值分别代表整个矩阵的列数,行数和元素数,后面的例子会更加清楚这点。

3.稀疏矩阵的转置。

对于稀疏矩阵的三元组表示形式的转置,相比标准表示形式,会有一些特别。需要找到第n列所有元素,并把他们存储在转置矩阵的第n行……

第一个版本的稀疏矩阵转置算法如下:

void transport1(term a[], term b[])
{
	int n, i, j, currentb;
	n = a[0].value;
	b[0].row = a[0].col;
	b[0].value = n;
	if( n > 0 ){
		currentb = 1;
		for( i = 0; i < a[0].col; i++)
			for( j = 1; j <= n; j++){
				if( a[j].col == i){
					b[currentb].row = a[j].col;
					b[currentb].col = a[j].row;
					b[currentb].value = a[j].value;
					currentb++;
				}
			}
	}
}

 

但是这个版本的算法运行效率是比较低的。可以看出,两个for循环的次数分别为col和n,也就是列数和总共的元素数量。所以时间复杂度是O(列数*元素数量)。当元素数量是col*row的时候,也就是说这个矩阵不是稀疏的了,没有非零元素了(貌似说成没有非零元素不对)。这时候花费的时间就太多了。这里有一个更好的算法,但是需要多一些的存储空间。

 

void transport2(term a[], term b[])
{
	int row_terms[MAX_COL], starting_pos[MAX_COL];
	int i, j, col = a[0].col;
	int num_terms = a[0].value;
	b[0].col = a[0].row;
	b[0].row = a[0].col;
	b[0].value = num_terms;
	if( num_terms > 0 ){
		for( i = 0; i < col; i++ ){
			row_terms[i] = 0;
		}
		for( i = 1; i <= num_terms; i++ ){
			row_terms[a[i].col]++;
		}
		starting_pos[0] = 1;
		for( i = 1; i < col; i++ ){
			starting_pos[i] = starting_pos[i-1] + row_terms[i-1];
		}
		for( i = 1; i <= num_terms; i++){
			 j = starting_pos[a[i].col]++;/*b的下标的计算*/
			 b[j].col = a[i].row;
			 b[j].row = a[i].col;
			 b[j].value = a[i].value;
		}
	}	
}


函数分析:第一个for循环将所有的row_terms置零,因为有的列本身就没有非零元素;第二个for循环计算有非零元素的列的非零元素的个数(为了在转置之后的term数组中,是按原矩阵的列递增来存储的);第三个for循环计算起始位置,是前一行非零元素个数的和加上前一个起始位置;第四个for循环转置的矩阵逐一生成。

四个for循环,这个函数的时间复杂度是O(col+元素数量),当元素数量是col*row时,时间变为O(col*row)。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值