用三元组存储稀疏矩阵并实现转置

基本概念

在学习线性代数的时候,经常用到矩阵。在C语言中,表示矩阵的最直观形式就是二维数组。然而在实际应用中,很多高阶矩阵中的非零元素非常少,这个时候如果继续使用二维数组存储,那么就会浪费很多存储空间。

在数据结构中,我们用三元组存储稀疏矩阵。三元组定义为(i,v,j),这三个值一次表示矩阵的行、列、值。


有了基本的概念之后,就可以定义数据结构了

定义一个结构体,来表示三元组的基本属性

typedef struct
{
	int row, col;
	int e;
}Triple;

然后再定义一个存储容器,用来存放三元组的

为了简单起见,我们用数组来实现,并定义最大存储单元MAXSIZE为100


typedef struct
{
	Triple data[MAXSIZE];
	Int m,n,len;
}TSMatrix;
//(TSMatrix表示 Triple Sparse Matrix)

实现矩阵的转置
         实现用三元组表示的矩阵的转置,可以直接把行列互换,然后再执行按行序为主的排序过程。为了避免重新排序引起的元素移动,可以采用列序递增转置法。

         具体做法,就是遍历列的下表值,从列数低的值到列数高的值,依次添加到缓存三元组中。很显然,这是一个双重for循环结构,内层循环实现遍历整个表,寻找合适的列。外层循环,则记录要寻找的列数。

//实现转置 
void TransposeTSMatrix(TSMatrix A, TSMatrix* B)
{
	int i,j,k;
	B->m = A.n;
	B->n = A.m;
	B->len = A.len;
	j=0;
	
	for( k=0; k<A.len; ++k)
	{
		for( i=0; i<A.len; ++i)
		{
			if(A.data[i].col == k)
			{
				B->data[j].row = A.data[i].col;
				B->data[j].col = A.data[i].row;
				B->data[j].e = A.data[i].e;
				++j;
			}
		}
	}
	
}

有了上面的基础,就可以写一个带有测试驱动的函数

完整代码

#include <stdio.h>
#define MAXSIZE 100
//三元组的定义 
typedef struct
{
	int row, col;//表示行列 
	int e;		//表示值 
}Triple;

//三元组容器的定义 
typedef struct
{
	Triple data[MAXSIZE];
	int m,n,len;
}TSMatrix;

//实现转置 
void TransposeTSMatrix(TSMatrix A, TSMatrix* B)
{
	int i,j,k;
	B->m = A.n;
	B->n = A.m;
	B->len = A.len;
	j=0;
	
	for( k=0; k<A.len; ++k)
	{
		for( i=0; i<A.len; ++i)
		{
			if(A.data[i].col == k)
			{
				B->data[j].row = A.data[i].col;
				B->data[j].col = A.data[i].row;
				B->data[j].e = A.data[i].e;
				++j;
			}
		}
	}
	
}

//测试驱动函数 
int main()
{
	//将输入重定向到根目录下的data.txt 
	freopen("data.txt", "r", stdin);
	TSMatrix A,B;
	int i,j,e; 
	int k=0;
	printf("请输入三元组:");
	while(scanf("%d%d%d", &i, &j, &e)!=EOF)
	{
		A.data[k].row = i-1;
		A.data[k].col = j-1;
		A.data[k].e = e;
		A.len = ++k;
	}
	printf("\n原始三元组为:\n");
	for(i=0; i<A.len; ++i )
	{
		printf("%3d%3d%3d\n", A.data[i].row+1, A.data[i].col+1, A.data[i].e);
	}
	
	printf("\n转置后:\n");
	TransposeTSMatrix(A, &B);
	for(i=0; i<B.len; ++i )
	{
		printf("%3d%3d%3d\n", B.data[i].row+1, B.data[i].col+1, B.data[i].e);
	}
	return 0;
}

程序截图



  • 57
    点赞
  • 358
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
以下是三元组存储稀疏矩阵快速转置的C语言实现算法: ```c #include <stdio.h> #include <stdlib.h> #define MAXSIZE 1000 // 定义三元组最大元素个数 // 三元组结构体 typedef struct { int i, j, e; // 行下标、列下标、元素值 } Triple; // 稀疏矩阵结构体 typedef struct { Triple data[MAXSIZE + 1]; // 三元组,data[0]未用 int mu, nu, tu; // 行数、列数、非零元素个数 } Matrix; // 稀疏矩阵转置 void Transpose(Matrix M, Matrix *T) { int p, q, col; int num[M.nu + 1]; int cpot[M.nu + 1]; T->mu = M.nu; T->nu = M.mu; T->tu = M.tu; if (T->tu) { for (col = 1; col <= M.nu; ++col) num[col] = 0; for (p = 1; p <= M.tu; ++p) ++num[M.data[p].j]; cpot[1] = 1; for (col = 2; col <= M.nu; ++col) cpot[col] = cpot[col - 1] + num[col - 1]; for (p = 1; p <= M.tu; ++p) { col = M.data[p].j; q = cpot[col]; T->data[q].i = M.data[p].j; T->data[q].j = M.data[p].i; T->data[q].e = M.data[p].e; ++cpot[col]; } } } int main() { Matrix M, T; int i, j, k; printf("请输入稀疏矩阵的行数、列数和非零元素个数:"); scanf("%d%d%d", &M.mu, &M.nu, &M.tu); printf("请输入稀疏矩阵三元组:\n"); for (k = 1; k <= M.tu; ++k) { scanf("%d%d%d", &M.data[k].i, &M.data[k].j, &M.data[k].e); } Transpose(M, &T); printf("转置后的稀疏矩阵三元组为:\n"); for (k = 1; k <= T.tu; ++k) { printf("%d %d %d\n", T.data[k].i, T.data[k].j, T.data[k].e); } return 0; } ``` 算法思路: - 遍历原稀疏矩阵中每个非零元素,统计每列非零元素个数并存储在num数组中。 - 根据num数组计算每列第一个非零元素在转置后的三元组中的位置并存储在cpot数组中。 - 遍历原稀疏矩阵中每个非零元素,将其转置存储转置后的三元组中。由于转置后的三元组是按列存储的,因此要先按列顺序遍历,再按行顺序存储

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值