C语言数据结构:稀疏矩阵的加法(三元组实现)

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


//常量定义
#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE -1
#define OVERFLOW   -2

typedef int ElemType;//抽象数据类型定义
typedef int    Status;//函数返回值

#define MAXSIZE 20 // 非零元个数的最大值

typedef struct {
	int    i, j; // 行下标,列下标
	ElemType e; // 非零元素值
}Triple;

typedef struct {
	Triple data[MAXSIZE + 1]; // 非零元三元组表,从data[1]开始使用
	int mu, nu, tu; // 矩阵的行数、列数和非零元个数
}TSMatrix;

void AtoT(int num[][MAXSIZE],TSMatrix *T)//二维数组转三元组
{
	T->tu = 1;
	for(int i=1;i<=T->mu;i++)
	{
		for(int j=1;j<=T->nu;j++)
		{
			if(num[i][j]!=0)
			{
				T->data[T->tu].i = i;
				T->data[T->tu].j = j;
				T->data[T->tu].e = num[i][j];
				T->tu++;
			}
		}
	}
	T->tu--;
}

void TtoA(TSMatrix T,int num[][MAXSIZE])//三元组转二维数组
{
	for(int i=1;i<=T.tu;i++)
	{
		num[T.data[i].i][T.data[i].j] = T.data[i].e;
	}
}

Status Create_Matrix(TSMatrix *T)
{
	int num[MAXSIZE][MAXSIZE]={0};
	printf("请输入稀疏矩阵的行数和列数\n");
	scanf("%d %d", &T->mu, &T->nu);

	printf("请输入稀疏矩阵的元素\n");
	for (int i = 1; i <= T->mu; i++)
	{
		for (int j = 1; j <= T->nu; j++)
		{
			scanf("%d", &num[i][j]);
		}
	}

	AtoT(num, T);//数组转三元组
}

// 输出稀疏矩阵M
void PrintSMatrix(TSMatrix M)
{
	int i,num[MAXSIZE][MAXSIZE]={0};
	printf(" %d 行, %d 列, %d 个非零元素。\n", M.mu, M.nu, M.tu);
	printf("三元组为:\n");
	printf("======================\n");
	printf("%4s %4s %4s\n", "i", "j", "e");
	printf("======================\n");
	for (i = 1; i <= M.tu; i++)
		printf("%4d %4d %4d\n", M.data[i].i, M.data[i].j, M.data[i].e);
	printf("======================\n");
	TtoA(M, num);
	printf("矩阵为:\n");
	printf("======================\n");
	for (int i = 1; i <= M.mu; i++)
	{
		for (int j = 1; j <= M.nu; j++)
		{
			printf("%4d", num[i][j]);
		}
		printf("\n");
	}
	printf("======================\n");
}



// 三元组表示的稀疏矩阵加法: C=A+B 
Status Matrix_Addition(TSMatrix A, TSMatrix B, TSMatrix *C)
{
	int row_a, row_b,col_a, col_b, index_a, index_b, index_c;
	//A元素的行号,B元素的行号,A元素的列号,B元素的列号,ABC矩阵三元组的地址

	//因为同类型矩阵才能相加,所以相加后的矩阵行和列和原来来两个矩阵的行列一样
	C->mu = A.mu;
	C->nu = A.nu;

	//行,列不相同的矩阵不能相加,返回ERROR
	if (A.mu != B.mu || A.nu != B.nu) {
		return ERROR;
	}

	//同时遍历两个三元组,开始都为1,因为0位置未存元素,当A或者B中其一元素取完循环终止
	for(index_a=1,index_b=1,index_c=1;index_a<=A.tu&&index_b<=B.tu;)
	{

		row_a = A.data[index_a].i;//A矩阵元素的行号
		row_b = B.data[index_b].i;//B矩阵元素的行号
		col_a = A.data[index_a].j;//A矩阵元素的列号
		col_b = B.data[index_b].j;//B矩阵元素的列号

		//因为三元组是按行和列排好序的所以比较行数先判断是否来自同一行
		if(row_a>row_b)//B的行号小于A直接将B中元素加入C矩阵
		{
			//复制B到C
			C->data[index_c].i = B.data[index_b].i;
			C->data[index_c].j = B.data[index_b].j;
			C->data[index_c].e = B.data[index_b].e;
			index_b++;//B矩阵地址加一表示向后取一个元素
			index_c++;//C矩阵地址加一表示下一元素存放的地址
		}
		else if(row_a<row_b)//B的行号大于A直接将A中元素加入C矩阵
		{
			//复制A到C
			C->data[index_c].i = A.data[index_a].i;
			C->data[index_c].j = A.data[index_a].j;
			C->data[index_c].e = A.data[index_a].e;
			index_a++;//A矩阵地址加一表示向后取一个元素
			index_c++;//C矩阵地址加一表示下一元素存放的地址
		}
		else//行号相同时
		{
			//在判断列好号是否来自同一行
			if(col_a>col_b)//B的列号小于A直接将B中元素加入C矩阵
			{
				//复制B到C
				C->data[index_c].i = B.data[index_b].i;
				C->data[index_c].j = B.data[index_b].j;
				C->data[index_c].e = B.data[index_b].e;
				index_b++;//B矩阵地址加一表示向后取一个元素
				index_c++;//C矩阵地址加一表示下一元素存放的地址
			}
			else if(col_a<col_b)//B的列号小于A直接将B中元素加入C矩
			{
				//复制A到C
				C->data[index_c].i = A.data[index_a].i;
				C->data[index_c].j = A.data[index_a].j;
				C->data[index_c].e = A.data[index_a].e;
				index_a++;//A矩阵地址加一表示向后取一个元素
				index_c++;//C矩阵地址加一表示下一元素存放的地址
			}
			else//相等
			{
				//判断元素相加是否为零
				if((A.data[index_a].e+B.data[index_b].e))//相加不为零
				{
					C->data[index_c].i = A.data[index_a].i;//赋值行号给C
					C->data[index_c].j = A.data[index_a].j;//赋值列号给C
					C->data[index_c].e = A.data[index_a].e + B.data[index_b].e;//赋值元素相加结果给C
					index_c++;C矩阵地址加一表示下一元素存放的地址
				}
				//无论相加是否为零都执行
				index_a++;//A矩阵地址加一表示向后取一个元素
				index_b++;//B矩阵地址加一表示向后取一个元素
			}
		}
	}

	while (index_a <= A.tu)//B取完A未取完
	{
		//将A中所剩元素依次加入到C中
		C->data[index_c].i = A.data[index_a].i;
		C->data[index_c].j = A.data[index_a].j;
		C->data[index_c].e = A.data[index_a].e;
		index_a++;
		index_c++;
	}

	while (index_b <= B.tu)//A取完B未取完
	{
		//将A中所剩元素依次加入到C中
		C->data[index_c].i = B.data[index_b].i;
		C->data[index_c].j = B.data[index_b].j;
		C->data[index_c].e = B.data[index_b].e;
		index_b++;
		index_c++;
	}
	C->tu = index_c - 1;//index_c是在执行完逻辑后加一的所以比实际上多1,因此C中元素的真实个数为index_c-1
	return OK;
}



int main()
{
	TSMatrix A,B,C;
	printf("创建矩阵A\n");
	Create_Matrix(&A);
	printf("矩阵A:\n");
	PrintSMatrix(A);
	printf("创建矩阵B\n");
	Create_Matrix(&B);
	printf("矩阵B:\n");
	PrintSMatrix(B);
	Matrix_Addition(A, B, &C);
	printf("矩阵A加加矩阵B后\n");
	PrintSMatrix(C);
}

请大佬多多指教,觉得写的好的给个赞赞哦/手动玫瑰

  • 67
    点赞
  • 226
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值