Basic operations on sparse matrices (ternary arrays) (C language)

This article has only code, and introduces basic operations on sparse matrices.

It has been debugged without any major problems.
If there are mistakes, please criticize and correct.

1. The storage representation of the triple sequence table of the sparse matrix:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

typedef int ElemType;
typedef int Status;

//稀疏矩阵的三元组顺序表存储表示
#define MAXSIZE 100  //假设非零元个数的最大值为100
#define MAXRC 20

typedef struct {
	int i, j;//该非零元的行下标和列下标
	ElemType e;
}Triple;
typedef struct {
	Triple data[MAXSIZE + 1];//非零元三元组表,data[0]未用
	int  rpos[MAXRC + 1];//每行第一个非零元素在data数组中的位置
	int mu, nu, tu;//矩阵的行数、列数和非零元个数
}TSMatrix;

2. Basic operations on sparse matrices:

//函数声明
Status CreateMatrix(TSMatrix* M);//创建稀疏矩阵CreateMatrix(&M)

Status DestroySMatrix(TSMatrix* M);//销毁稀疏矩阵DestroySMatrix(&M)

void PrintSMatrix(TSMatrix M);//输出稀疏矩阵PrintSMatrix(M)

void CopySMatrix(TSMatrix M, TSMatrix* T);//拷贝稀疏矩阵CopySMatrix(M, &T)

Status AddSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q);//矩阵相加AddSMatrix(M, N, &Q)

Status SubtSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q);//矩阵相减SubtSMatrix(M, N, &Q)

Status MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q);//矩阵相乘MultSMatrix(M, N, &Q)

Status TranspopseSMatrix(TSMatrix M, TSMatrix* T);//转置矩阵TranspopseSMatrix(M, &T)

Status comp(int c1, int c2);//比较两数大小comp(c1, c2)

1. Create a sparse matrix:

/*---------------------------------------------------------------------------------------
功能:创建稀疏矩阵
参数:1、稀疏矩阵指针
输出:OK、ERROR
*/
//创建稀疏矩阵CreateMatrix(&M)
Status CreateMatrix(TSMatrix* M)
{
	int i, j;
	for (i = 1; i < MAXRC + 1; i++)
		M->rpos[i] = 0;
	printf("请输入矩阵的行数,列数,非零元个数:");
	scanf("%d%d%d", &M->mu, &M->nu, &M->tu);
	for (i = 1; i <= M->tu; i++)
	{
		printf("请按行序顺序输入第i个非零元素所在的行,列,元素值:");
		scanf("%d%d%d", &M->data[i].i, &M->data[i].j, &M->data[i].e);
	}
	for (i = 1, j = 1; i <= M->mu; i++)
	{
		M->rpos[i] = j;
		while (M->data[j].i <= i && j <= M->tu)
		{
			j++;
		}
	}
	return OK;
}

2. Destroy the sparse matrix:

/*---------------------------------------------------------------------------------------
功能:销毁稀疏矩阵
参数:1、稀疏矩阵指针
输出:OK、ERROR
*/
//销毁稀疏矩阵DestroySMatrix(&M)
Status DestroySMatrix(TSMatrix* M)
{
	M->mu = M->nu = M->tu = 0;
	return OK;
}

3. Output sparse matrix:

/*---------------------------------------------------------------------------------------
功能:输出稀疏矩阵
参数:1、稀疏矩阵
输出:空
*/
//输出稀疏矩阵PrintSMatrix(M)
void PrintSMatrix(TSMatrix M)
{
	int i, j, k = 1;//非零元计数器,初值为1
	Triple* p = M.data + 1;//p指向M的第一个非零元素
	for (i = 1; i <= M.mu; i++)
	{
		for (j = 1; j <= M.nu; j++)
		{
			if (k <= M.tu && p->i == i && p->j == j)//p指向非零元,且p所指元素为当前循环在处理的元素
			{
				printf("%3d ", p->e);
				p++;
				k++;
			}
			else//p所指元素不是当前循环在处理的元素
			{
				printf("%3d ", 0);
			}
		}
		printf("\n");
	}
}

4. Copy the sparse matrix:

/*---------------------------------------------------------------------------------------
功能:拷贝稀疏矩阵
参数:1、稀疏矩阵 2、稀疏矩阵指针
输出:空
*/
//拷贝稀疏矩阵CopySMatrix(M, &T)
void CopySMatrix(TSMatrix M, TSMatrix* T)
{
	*T = M;
}

5. Matrix addition:

/*---------------------------------------------------------------------------------------
功能:矩阵相加
参数:1、稀疏矩阵 2、稀疏矩阵 3、稀疏矩阵指针
输出:OK、ERROR
*/
//矩阵相加AddSMatrix(M, N, &Q)
Status AddSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q)
{
	int m = 1, n = 1, q = 0;
	if (M.mu != N.mu || M.nu != N.nu)//矩阵行列数不等
		return ERROR;
	Q->mu = M.mu;
	Q->nu = M.nu;
	while (m <= M.tu && n <= N.tu)//矩阵相加
	{
		switch (comp(M.data[m].i, N.data[n].i))
		{
		case -1:
			Q->data[++q] = M.data[m++];
			break;
		case 0:
			switch (comp(M.data[m].j, N.data[n].j))
			{
			case -1:
				Q->data[++q] = M.data[m++];
				break;
			case 0:
				Q->data[++q] = M.data[m++];
				Q->data[q].e += N.data[n++].e;//行列都相等时相加
				if (Q->data[q].e == 0)
				{
					q--;
				}
				break;
			case 1:
				Q->data[++q] = N.data[n++];
				break;
			}
			  break;
		case 1:
			Q->data[++q] = N.data[n++];
			break;
		}
	}
	while (m <= M.tu)//M矩阵剩余的三元数组加入Q中
	{
		Q->data[++q] = M.data[m++];
	}
	while (n <= N.tu)//N矩阵剩余的三元数组加入Q中
	{
		Q->data[++q] = N.data[n++];
	}
	if (q > MAXSIZE)//超过矩阵最大非零个数
	{
		return ERROR;
	}
	Q->tu = q;
	return OK;
}

6. Matrix subtraction:

/*---------------------------------------------------------------------------------------
功能:矩阵相减
参数:1、稀疏矩阵 2、稀疏矩阵 3、稀疏矩阵指针
输出:OK、ERROR
*/
//矩阵相减SubtSMatrix(M, N, &Q)
Status SubtSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q)
{
	int i;
	if (M.mu != N.mu || M.nu != N.nu)//矩阵行列数不等
		return ERROR;
	for (i = 1; i <= N.tu; i++)//(-N)
	{
		N.data[i].e *= -1;
	}
	return AddSMatrix(M, N, Q); //Q=M+(-N);
}

7. Matrix multiplication:

/*---------------------------------------------------------------------------------------
功能:矩阵相乘
参数:1、稀疏矩阵 2、稀疏矩阵 3、稀疏矩阵指针
输出:OK、ERROR
*/
//矩阵相乘MultSMatrix(M, N, &Q)
Status MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q)
{
	int arow, brow, p, q, ccol, ctemp[MAXRC + 1], t, tp;
	if (M.nu != N.mu)//M的行数与N的列数不等
	{
		return ERROR;
	}
	Q->mu = M.mu;
	Q->nu = N.nu;
	Q->tu = 0;
	if (M.tu * N.tu != 0)//Q是非零矩阵
	{
		for (arow = 1; arow <= M.mu; arow++)//从M的第一行开始,到最后一行,arow是M的当前行
		{
			for (ccol = 1; ccol <= N.nu; ccol++)//从Q的第一列到最后一列
			{
				ctemp[ccol] = 0;  //Q的当前行的各列元素累加器清零
			}
			Q->rpos[arow] = Q->tu + 1;
			if (arow < M.mu)
			{
				tp = M.rpos[arow + 1];
			}
			else
			{
				tp = M.tu + 1;
			}
			for (p = M.rpos[arow]; p < tp; p++)
			{
				brow = M.data[p].j;
				if (brow < N.mu)
				{
					t = N.rpos[brow + 1];
				}
				else
				{
					t = N.tu + 1;
				}
				for (q = N.rpos[brow]; q < t; q++)
				{
					ccol = N.data[q].j;
					ctemp[ccol] += M.data[p].e * N.data[q].e;
				}
			}
			for (ccol = 1; ccol <= Q->nu; ccol++)
			{
				if (ctemp[ccol])
				{
					if (++Q->tu > MAXSIZE)
						return ERROR;
					Q->data[Q->tu].i = arow;
					Q->data[Q->tu].j = ccol;
					Q->data[Q->tu].e = ctemp[ccol];
				}
			}
		}
	}
	return OK;
}

8. Transpose matrix:

/*---------------------------------------------------------------------------------------
功能:转置矩阵
参数:1、稀疏矩阵 2、稀疏矩阵指针
输出:OK、ERROR
*/
//转置矩阵TranspopseSMatrix(M, &T)
Status TranspopseSMatrix(TSMatrix M, TSMatrix* T)
{
	int p = 0, q = 1, row = 0; //q指示转置矩阵T的当前元素
	T->mu = M.nu;//列变行
	T->nu = T->mu;//行变列
	T->tu = M.tu;//非零元个数相同
	for (row = 1; row < M.nu; ++row)
	{
		for (p = 1; p <= M.tu; ++p)
		{
			if (M.data[p].j == row)//交换行和列
			{
				T->data[q].i = M.data[p].j;
				T->data[q].j = M.data[p].i;
				T->data[q].e = M.data[p].e;
				++q;
			}
		}
	}
	return OK;
}

9. Compare the size of two numbers:

/*---------------------------------------------------------------------------------------
功能:比较两数大小
参数:1、整数 2、整数
输出:-1、0、1
*/
//比较两数大小comp(c1, c2)
Status comp(int c1, int c2)
{
	if (c1 < c2)
	{
		return -1;
	}
	else if (c1 == c2)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}

3. Test the main program:

int main()
{
	TSMatrix A, B, C, D, T;
	printf("创建稀疏矩阵A:\n");
	CreateMatrix(&A);
	printf("输出矩阵A:\n");
	PrintSMatrix(A);

	printf("输出A的转置矩阵T:\n");
	TranspopseSMatrix(A, &T);
	PrintSMatrix(T);

	printf("复制矩阵A得B,输出B:\n");
	CopySMatrix(A, &B);
	PrintSMatrix(B);

	printf("输入矩阵C:\n");
	CreateMatrix(&C);
	PrintSMatrix(C);

	printf("输出矩阵A和矩阵C的和:\n");
	AddSMatrix(A, C, &D);
	PrintSMatrix(D);

	printf("输出矩阵A和矩阵C的差:\n");
	SubtSMatrix(A, C, &D);
	PrintSMatrix(D);

	DestroySMatrix(&A);
	DestroySMatrix(&B);
	DestroySMatrix(&C);

	printf("创建稀疏矩阵A:\n");
	CreateMatrix(&A);
	PrintSMatrix(A);
	printf("创建稀疏矩阵B:\n");
	CreateMatrix(&B);
	PrintSMatrix(B);
	printf("输出矩阵A和B的乘积C:\n");
	MultSMatrix(A, B, &C);
	PrintSMatrix(C);

	system("pause");
	return 0;
}

Guess you like

Origin blog.csdn.net/absorb2601078490/article/details/125016780