矩阵与数组(2)

三元组表表示的矩阵相加

题目描述

假设稀疏矩阵A和B(以两行四列的矩阵为例)均以三元组顺序表作为存储结构,试写出矩阵相加的算法,另设三元组表C存放结果矩阵。

输入样例

1 0 0 0
0 -2 0 0
0 0 0 1
5 2 1 0

输出样例

矩阵M:
1  0  0  0
0 -2  0  0

矩阵N:
0  0  0  1
5  2  1  0

矩阵M和矩阵N的和:
1  0  0  1
5  0  1  0

代码如下

#include <stdio.h>
#define MAXSIZE 12500
#define m 2//行 
#define n 4//列 
typedef struct
{
	int row,column,e;//三元组,记录元素的行、列、和值 
}Triple;
typedef struct
{
	Triple data[MAXSIZE+1];
	int tu;//非零元的个数,行数列数已固定,不再定义mu,tu;	 
}TMatrix;
 void InitMatrix(int X[m][n],TMatrix * R)//输入 
 {  
    int i,j,s; 
	R->tu=0;//初始化 
	for(i=0;i<m;i++)
	{
	  for(j=0;j<n;j++)
	  {
	  	scanf("%d",&X[i][j]);
	  	if(X[i][j]!=0)
	  	{
	  		(R->tu)++;//记录输入矩阵非零元个数 
			R->data[R->tu].row=i;
			R->data[R->tu].column=j;
			R->data[R->tu].e=X[i][j];	
		}
	  }
	} 
 }
 void MatrixAdd(TMatrix * A,TMatrix * B,TMatrix * C)//相加
{
 	int p=1,q=1,k=1;  //遍历三元组,用于循环控制矩阵 A,B,C 
	int an=A->tu,bn=B->tu;//A、B两个矩阵三元组元素的个数 
	while(p<=an&&q<=bn)//直至遍历完其中一个三元组,结束循环
	{                   
		if(A->data[p].row<B->data[q].row) 
		{  //A矩阵中元素的行标小于B矩阵中元素的行标,即:A的元素在前面 
			//矩阵 A和B没有相同行,也就没有相同列,所以直接把A的复制给C 
			C->data[k]=A->data[p];
			p++;k++;  //A矩阵三元组完成了一个元素的加操作,C矩阵也存入了一个元素 
		}
		
		 else if(A->data[p].row==B->data[q].row)//矩阵A和B有相同行,接下来判断是否有相同列
		 { 
			if(A->data[p].column<B->data[q].column)//矩阵A和B有相同行,A的元素的列数更小,排在前面 
			{
				C->data[k]=A->data[p];
				p++;k++;  //A矩阵完成了一个元素的加操作,C矩阵也存入了一个元素 
			}else if(A->data[p].column==B->data[q].column)//行列均相同 
			{
				C->data[k].e=A->data[p].e+B->data[q].e;
				C->data[k].row=A->data[p].row;
				C->data[k].column=A->data[p].column;
				p++;q++;
				if(C->data[k].e!=0) //其实判不判断都不影响输出结果,但为了保证后面非零元个数的严谨性,还是判断一下相加后的和是否为0恰当 
				k++;
			}
			else//矩阵 A和B有相同行但B的元素靠前,所以直接把B的复制给C
			{	 
				C->data[k]=B->data[q];
				q++;k++;  //B矩阵完成了一个元素的加操作 C矩阵也存入了一个元素 
			}
		 }
		 
		 else //A矩阵中元素的行标大于B矩阵中元素的行标 ,即B的元素在前 
		   {   
			//矩阵A和B没有相同行,也就没有相同列,所以直接把B的复制给C 
			C->data[k]=B->data[q];
			q++;k++;  //B矩阵完成了一个元素的加操作,C矩阵也存入了一个元素 
		   }
	}
	while(p<=an)//A矩阵的非零元没用完 
	{
		C->data[k]=A->data[p];
		p++;k++;
	}
	while(q<=bn)//B矩阵的非零元没用完 
	{
		C->data[k]=B->data[q];
		q++;k++;  
	}
	C->tu=k-1;//k从1开始,算个数自然要减去1 
}
void PrintMatrix(char name[],TMatrix * C)//输出
{
   	 int i,j,p;
   	 puts(name);
	 int Z[m][n]={0}; //先全赋值为0 
	 for(p=1;p<=C->tu;p++)
	 {	
	   Z[C->data[p].row][C->data[p].column]=C->data[p].e;//再把非零元赋值 
     }
  	for(i=0;i<m;i++)
	{
	  for(j=0;j<n;j++)
	  {
	  	printf("%-3d ",Z[i][j]);
	  }
	  printf("\n");
	} 
}//由新的三元组表还原新的矩阵 
int main()
{
	int a[m][n],b[m][n];
  	TMatrix M,N,T,*P,*Q,*U;//用指针做更方便 
  	P=&M;
  	Q=&N;
  	U=&T;
	InitMatrix(a,P);
	InitMatrix(b,Q);
	PrintMatrix("矩阵M:",P);
	printf("\n");
	PrintMatrix("矩阵N:",Q);
	printf("\n");
	MatrixAdd(P,Q,U);
	PrintMatrix("矩阵M和矩阵N的和:",U);
	return 0;	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值