稀疏矩阵的转置算法

稀疏矩阵的提出是基于存储的高效率考虑的,由于实际生活中不是每一个数据都是需要保存或记录的,或者说有很多数据都是重复的,比如都是0或者1等,那么就可以将不需要的数据抽象成数字0,或者是把相同的数据抽象成0,这样就只需要记录原数据量-不需要的数据量了,在这里,我们原本用一个矩阵记录数据,(称0元素比非零元素多的矩阵为稀疏矩阵),现在则可以用一个三元结点数组来等价表达了,方法是用行优先或者是列优先的顺序来顺次记录原矩阵中非零的元素,而三元结点中包含数据的行号,列号,和值。这样就可以在三元结点数组与矩阵之间建立一种一一对应的关系了,由于不需要记录不必要的数据,所以大大节省了存储空间。

那么现在我们讨论的问题是:当一个矩阵发生转置时,对应转置后的矩阵的三元结点数组是什么?或者说,如何由原三元数组来求转置后的三元结点数组,注意这里的三元结点数组都是以行优先(或列优先)存放数据的,如果不是这样的矩阵,那么就不能用该算法,下面是代码:

//稀疏矩阵的转置算法
#include <stdio.h>
#include <stdlib.h>
#define Max 100
typedef struct{
	int row;
	int col;
	int value;
}trim;
typedef struct nutrim{
	trim node[Max]; //最多为Max-1个非零元素
	int m,n,num;
}nutrim,*pnutrim;

void transfor(pnutrim t){
	printf("请输入稀疏矩阵的行数与列数以及非零元素:\n");
	scanf("%d,%d,%d",&t->m,&t->n,&t->num);
	if(t->num==0)
		return ;
	int i,j,k=1;
	printf("请输入非零元素的行号列号以及值,行优先\n");
	for(i=1;i<=t->num;i++)
		scanf("%d,%d,%d",&t->node[i].row,&t->node[i].col,&t->node[i].value);
    pnutrim s=(pnutrim)malloc(sizeof(nutrim));
	for(i=1;i<=t->n;i++)
		for(j=1;j<=t->num;j++)
			if(t->node[j].col==i){
				s->node[k].row=t->node[j].col;
				s->node[k].col=t->node[j].row;
				s->node[k++].value=t->node[j].value;
			}
	s->m=t->n;
	s->n=t->m;
	s->num=t->num;
	printf("转置后的稀疏矩阵三元组表示,行优先:\n");
	for(i=1;i<=s->num;i++)
		printf("%d,%d,%d\n",s->node[i].row,s->node[i].col,s->node[i].value);
	free(s);
}

int main(){
	nutrim p;
	pnutrim q=&p;
	transfor(q);
	return 0;
}

	
		
下面是测试数据:

请输入稀疏矩阵的行数与列数以及非零元素:
6,7,8
请输入非零元素的行号列号以及值,行优先
1,2,12
1,3,9
3,1,-3
4,3,24
5,2,18
6,1,15
6,4,-7
6,5,7
转置后的稀疏矩阵三元组表示,行优先:
1,3,-3
1,6,15
2,1,12
2,5,18
3,1,9
3,4,24
4,6,-7
5,6,7




Terminated with return code 0
Press any key to continue ...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值