1. 程式人生 > >陣列12——稀疏矩陣的壓縮儲存2——稀疏矩陣的相加

陣列12——稀疏矩陣的壓縮儲存2——稀疏矩陣的相加

設有兩個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;
}

結果: