三元组实现稀疏矩阵的压缩存储与转置 (Sparse matrix compression storage and transposition base on triple)

问题描述:用三元组压缩储存 一个row行,col列稀疏矩阵的非0元,并实现转置功能

PS:本文使用了两种不同算法实现稀疏矩阵的转置与存储功能,复杂度分别为O(A.mu*A.nu) 和  O(A.nu+A.tu)

步骤:利用数组和结构体建立三元组->输入稀疏矩阵的值->用三元组A保存非0元

算法1:扫描col次旧三元组A,依次将列号为"1,2....col"的非零元行列号交换后存放到新三元组B中

算法2:扫描一遍三元组A,用Num[col]存放矩阵B中每一行非零元的个数
            扫描一遍三元组A,用Cpot[col]存放矩阵B中每一行非零元的当前存放位置,初始时为每一行第一个非零元存放的位置
            对旧三元组A进行扫描,将每个元素依次取出,按照 Cpot[col]里的存放位置,依次放入新三元组B中,操作完成后对应的Cpot[col]加一

代码如下:

#include<iostream>
#include<cstdio>
int const MAXSIZE = 12500;      //稀疏矩阵大小
int const row = 3;
int const col = 5;              //当前默认的稀疏矩阵规格

typedef struct Triple		//三元组定义
{
	int i, j;	        //非0元下标
	int e;			//非0元的值
}Triple;

typedef struct TSMatrix         //稀疏矩阵类型
{
	Triple data[MAXSIZE+1];
	int mu, nu, tu;		//矩阵行数、列数、非0元个数
}TSMatrix;

int TSMatrix_Create(TSMatrix &A)//建立一个稀疏矩阵
{
	A.mu = row;
	A.nu = col;
	A.tu = 0;
	int k, r;
	printf("请输入%d行%d列的稀疏矩阵:\n", row, col);
	for (k = 1; k <= A.mu*A.nu; k++)
		scanf_s("%d", &A.data[k].e);
	for (k = 1; k <= A.mu*A.nu; k++)
		if (A.data[k].e != 0)
		{
			A.tu++;
			if (k%A.nu != 0)
			{
				A.data[k].i = k / A.nu + 1;
				A.data[k].j = k % A.nu;
			}
			else
			{
				A.data[k].i = k / A.nu;
				A.data[k].j = A.nu;
			}
		}
	for (k = 1, r = 0; k <= A.mu*A.nu; k++)
		if (A.data[k].e != 0)
			A.data[++r] = A.data[k];
	return 1;
}

int TSMatrix_Transpose1(TSMatrix A, TSMatrix &B)//O(A.mu*A.nu)
{
	B.mu = A.nu;  
	B.nu = A.mu;  
	B.tu = A.tu;
	int p, q, r;
	if (B.tu)
	{
		r = 1;
		for (p = 1; p <= A.nu; p++)
			for (q = 1; q <= A.tu; q++)
				if (A.data[q].j == p)
				{
					B.data[r].i = A.data[q].j;
					B.data[r].j = A.data[q].i;
					B.data[r].e = A.data[q].e;
					r++;
				}
	}
	for (r = 1; r <= B.tu; r++)
		printf("%d %d %d\n", B.data[r].i, B.data[r].j, B.data[r].e);
	return 1;
}

int TSMatrix_Transpose2(TSMatrix A, TSMatrix &B)//O(A.nu+A.tu)
{
	B.mu = A.nu;
	B.nu = A.mu;
	B.tu = A.tu;
	int Num[col+1], Cpot[col+1], p, q, Col;
	memset(Num, 0, sizeof(Num));
	memset(Cpot, 0, sizeof(Cpot));
	if (B.tu)
	{
		for (p = 1; p <= A.nu; p++)
			Num[A.data[p].j]++;
		Cpot[1] = 1;
		for (p = 2; p <= A.nu; p++)
			Cpot[p] = Cpot[p - 1] + Num[p - 1];
		for (p = 1; p <= A.tu; p++)
		{
			Col = A.data[p].j; 
			q = Cpot[Col]; 
			B.data[q].i = A.data[p].j; 
			B.data[q].j = A.data[p].i; 
			B.data[q].e = A.data[p].e; 
			++Cpot[Col];
		}
	}
	for (p = 1; p <= B.tu; p++)
		printf("%d %d %d\n", B.data[p].i, B.data[p].j, B.data[p].e);
	return 1;
}

int main()
{
	TSMatrix A, B;
	TSMatrix_Create(A);
	TSMatrix_Transpose1(A, B);//O(A.mu*A.nu)       
	TSMatrix_Transpose2(A, B);//O(A.nu+A.tu)
	system("pause");
}
编译环境:Visual Studio

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值