数组12——稀疏矩阵的压缩存储2——稀疏矩阵的相加

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_36669549/article/details/85079686

设有两个4*4的稀疏矩阵A和B,相加得到C,如图所示,请编写算法,要求利用三元组表示法实现两个稀疏矩阵的相加,并用矩阵形式输出结果。


【分析】

先比较两个稀疏矩阵的    先比较两个稀疏矩阵A和B的行号,如果行号相等,则比较列号;如果行号与列号都相等,则将对应的元素值相加,并将下标m与n下标都加1比较下一个元素;如果行号相等,列号不相等,则将列号较小的矩阵的元素赋给矩阵C,并将列号小的下标继续比较下一个元素;如果行号与列号都不相等,则将行号较小的矩阵的元素赋给C,并将行号小的下标比较下一个元素。
将两个矩阵中对应元素相加,需要考虑以下3种情况:
(1)A中的元素aij≠0且B中的元素bij≠0,但是结果可为零,若结果为零则不保存该元素如果结果不为零,则将结果保存到C中。
(2)A中的第(i,j)个位置存在非零元素aij,而B中不存在非零,则只需要将该值赋给C。
(3)B中的第(i打个位置存在非零元素bij,而A中不存在非零元素,则只需要将该值赋给C。
为了将结果以矩阵形式输出,可以先将一个二维数组全部元素初始化为0,然后确定每一个非零元素的行号和列号,将该非零元素存入到对应位置即可,最后输’出该二维数组。

TriSeqMatrix.h

#define MaxSize 200
typedef struct			/*三元组类型定义*/
{
	int i; 				/*非零元素的行号*/
	int j; 				/*非零元素的列号*/
    DataType e;
}Triple;
typedef struct				/*矩阵类型定义*/
{
    Triple data[MaxSize];
	int m; 			/*矩阵的行数*/
	int n; 			/*矩阵的列数*/
	int len; 			/*矩阵中非零元素的个数*/
}TriSeqMatrix;
int CreateMatrix(TriSeqMatrix *M)
/*创建稀疏矩阵(按照行优先顺序输入非零元素值)*/
{ 
	int i,m,n;
	DataType e;
	int flag;
	printf("请输入稀疏矩阵的行数、列数及非零元素个数:");
	scanf("%d,%d,%d",&M->m,&M->n,&M->len);
	if(M->len>MaxSize)
		return 0;
	for(i=0;i<M->len;i++)
	{
		do
		{
			printf("请按行序顺序输入第%d个非零元素所在的行(0~%d),列(0~%d),元素值:",i+1,M->m-1,M->n-1);
			scanf("%d,%d,%d",&m,&n,&e);
			flag=0;							/*初始化标志位*/
			if(m<0||m>M->m||n<0||n>M->n)			/*如果行号或列号正确,标志位为1*/
				flag=1;                        
			/*若输入的顺序正确,则标志位为1*/
			if(i>0&&m<M->data[i-1].i||m==M->data[i-1].i&&n<=M->data[i-1].j)	
				flag=1;
		}while(flag);
		M->data[i].i=m;
		M->data[i].j=n;
		M->data[i].e=e;
	}
	return 1;
}
void CopyMatrix(TriSeqMatrix M,TriSeqMatrix *N)
/*由稀疏矩阵M复制得到另一个副本N*/
{ 
	
	int i;
	N->len=M.len;				/*修改稀疏矩阵N的非零元素的个数*/
	N->m=M.m;				/*修改稀疏矩阵N的行数*/
	N->n=M.n;				/*修改稀疏矩阵N的列数*/
	for(i=0;i<M.len;i++)	/*把M中非零元素的行号、列号及元素值依次赋值给N的行号、列号及元素值*/
	{
		N->data[i].i=M.data[i].i;
		N->data[i].j=M.data[i].j;
		N->data[i].e=M.data[i].e;
	}
}
void TransposeMatrix(TriSeqMatrix M,TriSeqMatrix *N)
/*稀疏矩阵的转置*/
{ 
	int i,k,col;
	N->m=M.n;
	N->n=M.m;
	N->len=M.len;
	if(N->len)
	{
		k=0;
		for(col=0;col<M.n;col++)			/*按照列号扫描三元组顺序表*/
			for(i=0;i<M.len;i++)
				if(M.data[i].j==col)		/*如果元素的列号是当前列,则进行转置*/
				{
					N->data[k].i=M.data[i].j;
					N->data[k].j=M.data[i].i;
					N->data[k].e=M.data[i].e;
					k++;
				}
	}
}

void DestroyMatrix(TriSeqMatrix *M)
/*销毁稀疏矩阵*/
{ 
	M->m=M->n=M->len=0;
}

main.cpp

#include<stdlib.h>
#include<stdio.h>
#include<malloc.h>
#include<iostream>
#include<iomanip>

using namespace std;
typedef int DataType;
#include"TriSeqMatrix.h"
int AddMatrix(TriSeqMatrix A, TriSeqMatrix B, TriSeqMatrix *C);
void PrintMatrix(TriSeqMatrix M);
void PrintMatrix2(TriSeqMatrix M);
int CreateMatrix(TriSeqMatrix *M);
int CompareElement(int a, int b);
void main()
{
	TriSeqMatrix M, N, Q;
	CreateMatrix(&M);
	PrintMatrix2(M);
	CreateMatrix(&N);
	PrintMatrix2(N);
	AddMatrix(M, N, &Q);
	PrintMatrix(Q);
	PrintMatrix2(Q);

	system("pause");
}
void PrintMatrix(TriSeqMatrix M)
/*输出稀疏矩阵*/
{
	int i;
	cout << "稀疏矩阵是" << M.m << "行×" << M.n << "列,共" << M.len << "个非零元素" << endl;
	cout << "行    列    元素值" << endl;
	for (i = 0; i < M.len; i++)
		cout << setw(2) << M.data[i].i << setw(6) << M.data[i].j << setw(8) << M.data[i].e << endl;
}
void PrintMatrix2(TriSeqMatrix M)
/*按矩阵样式输出稀疏矩阵*/
{
	int k, i, j;
	DataType a[MaxSize][MaxSize];
	for (i = 0; i < M.m; i++)//初始化数组a,全部元素置为0
		for (j = 0; j < M.n; j++)
			a[i][j] = 0;
	for (k = 0; k < M.len; k++)//将非0元素存入数组a
	{
		if (M.data[k].e != 0)
		{
			i = M.data[k].i;
			j = M.data[k].j;
			a[i][j] = M.data[k].e;
		}
	}
	cout << "稀疏矩阵(按矩阵形式输出):" << endl;
	for (i = 0; i < M.m; i++)//按矩阵形式输出数组a中的元素
	{
		for (j = 0; j < M.n; j++)
			cout << setw(4) << a[i][j];
		cout << endl;
	}
}
int AddMatrix(TriSeqMatrix A, TriSeqMatrix B, TriSeqMatrix *C)
/*将两个矩阵A和B对应的元素值相加,得到另一个稀疏矩阵C*/
{
	int m = 0, n = 0, k = -1;
	if (A.m != B.m || A.n != B.n) /*如果两个矩阵的行数与列数不相等,则不能够进行相加运算*/
		return 0;
	C->m = A.m;
	C->n = A.n;
	while (m < A.len&&n < B.len)
	{
		switch (CompareElement(A.data[m].i, B.data[n].i))/*比较两个矩阵对应元素的行号*/
		{
		case -1:
			C->data[++k] = A.data[m++];	/*将矩阵A,即行号小的元素赋值给C*/
			break;
		case  0:
			/*如果矩阵A和B的行号相等,则比较列号*/
			switch (CompareElement(A.data[m].j, B.data[n].j))
			{
			case -1:					/*如果A的列号小于B的列号,则将矩阵A的元素赋值给C*/
				C->data[++k] = A.data[m++];
				break;
			case  0:					/*如果A和B的行号、列号均相等,则将两元素相加,存入C*/
				C->data[++k] = A.data[m++];
				C->data[k].e += B.data[n++].e;
				if (C->data[k].e == 0)		/*如果两个元素的和为0,则不保存*/
					k--;
				break;
			case  1:					/*如果A的列号大于B的列号,则将矩阵B的元素赋值给C*/
				C->data[++k] = B.data[n++];
			}
			break;
		case  1:						/*如果A的行号大于B的行号,则将矩阵B的元素赋值给C*/
			C->data[++k] = B.data[n++];
		}
	}
	while (m < A.len)						/*如果矩阵A的元素还没处理完毕,则将A中的元素赋值给C*/
		C->data[++k] = A.data[m++];
	while (n < B.len)						/*如果矩阵B的元素还没处理完毕,则将B中的元素赋值给C*/
		C->data[++k] = B.data[n++];
	C->len = k + 1;							/*修改非零元素的个数*/
	if (k > MaxSize)
		return 0;
	return 1;
}
int CompareElement(int a, int b)
/*比较两个矩阵的元素值大小。前者小于后者,返回-1;相等,返回0;大于,返回1*/
{
	if (a < b)
		return -1;
	if (a == b)
		return 0;
	return 1;
}

结果:

猜你喜欢

转载自blog.csdn.net/baidu_36669549/article/details/85079686