【数据结构】实现稀疏矩阵(采用三元组表示)的基本运算C语言/C++实现(代码有注释)


产出

CSDN 技术博客 1 篇

一、问题

实现稀疏矩阵(采用三元组表示)的基本运算
目的:领会稀疏矩阵三元组的存储结构及其基本算法设计。
内容:假设 nn 的稀疏矩阵 A 采用三元组表示,设计一个程序 exp6-1.cpp,实现如下功能:。

  1. 生成如下两个稀疏矩阵的三元组 a 和 b。
    在这里插入图片描述

  2. 输出 a 转置矩阵的三元组。

  3. 输出 a+b 的三元组。

  4. 输出 ab 的三元组。
    提示:本实验设计的功能算法如下
    ➢ CreatMat(TSMatrix &t,ElemType A[N][N]) //产生稀疏矩阵 A 的三元组表示 t
    ➢ DispMat(TSMatrix t) //输出三元组表示 t
    ➢ TranMat(TSMatrix t,TSMatrix &tb) //求三元组表示 t 的转置矩阵 tb
    ➢ MatAdd(TSMatrix a,TSMatrix b,TSMatrix &c) //求 c=a+b
    ➢ getvalue(TSMatrix t,int i,int j) //返回三元组 t 表示的 A[i][j]值
    ➢ MatMul(TSMatrix a,TSMatrix b,TSMatrix &c) //求 c=a×b
    执行结果类似于下图:
    在这里插入图片描述

二、思路分析

1、直接对三元组进行相关运算(该文代码思路)
2、先对稀疏矩阵进行运算,在生成三元组

三、代码实现

代码如下:

#include <stdio.h>

#define MaxSize 100//矩阵中非零元素最多个数
#define N 4			//稀疏矩阵行数
#define M 4			//稀疏矩阵列数
typedef int elem;
typedef struct
{
	int r;			//行数
	int c;			//列数
	elem d;			//数据元素
}TupNode;			//三元组定义

typedef struct
{
	int row;				//行数值
	int cols;				//列数值
	int nums;				//非零元素个数
	TupNode data[MaxSize];	//存放数组
}TSMatrix;					//三元组顺序表定义

//生成稀疏矩阵A三元组
void CreatMat(TSMatrix &t, elem A[N][M])
{
	int i, j;
	t.row = N;			//总行数
	t.cols = M;			//总列数
	t.nums = 0;			//总非零元素数,初始为零
	for(i = 0; i < N; i++)//遍历数组A
	{
		for(j = 0; j < M; j++)
		{
			if(A[i][j] != 0)				//判断是否为非零元素
			{
				t.data[t.nums].r = i;		//记录非零元素所在的行数
				t.data[t.nums].c = j;		//记录非零元素所在的列数
				t.data[t.nums].d = A[i][j];	//记录非零元素值
				t.nums++;					//非零元素个数加一
			}
		}
	}
} 

//输出三元组
void DipMat(TSMatrix t)
{
	int i;
	if(t.nums <= 0)//判断是否有非零元素
		return;
	printf("\t%d\t%d\t%d\n",t.row, t.cols, t.nums);
	printf("-------------------------------------\n");
	for(i = 0; i < t.nums; i++)
		printf("\t%d\t%d\t%d\n",t.data[i].r, t.data[i].c, t.data[i].d);
}

//三元组转置
void TranTat(TSMatrix t, TSMatrix &tb)
{
	int p, q = 0, v;		//q为ta.data的下标,v进行计数,p为t.data的下标
	tb.row = t.cols;		//总行数和总列数互换
	tb.cols = t.row;
	tb.nums = t.nums;		//非零元素个数
	if(t.nums != 0)			//当存在非零元素时进行转置
	{
		for(v = 0; v < t.cols; v++)//t列数为ta的行数
		{
			for(p = 0; p < t.nums; p++)
				if(t.data[p].c == v)
				{
					tb.data[q].r = t.data[p].c;//行列互换
					tb.data[q].c = t.data[p].r;
					tb.data[q].d = t.data[p].d;//元素值传递
					q++;						//下一个data
				}
		}
	}
}

//两个稀疏矩阵相加后对应的三元组
void MatAdd(TSMatrix a, TSMatrix b, TSMatrix &c)
{
	if(a.row != b.row || a.cols != b.cols)//判断是否符合矩阵相加条件,即两矩阵行数和列数分别相等
	{
		printf("矩阵相加操作失败\n");
		return;
	}
	c.row = a.row;						//总行数赋值
	c.cols = a.cols;					//总列数赋值
	int i = 0 , j = 0, k = 0;
	while(i < a.nums || j < b.nums)		//遍历两个三元组
	{
		if(a.data[i].r < b.data[j].r)//比较非零数值所在的行数大小,将较小的行数的非零数值放进c的三元组
		{
			c.data[k].r = a.data[i].r;
			c.data[k].c = a.data[i].c;
			c.data[k].d = a.data[i].d;
			i++;
			k++;
		}
		else if(a.data[i].r == b.data[j].r)//比较非零数值所在的行数大小,相等时
		{
			if(a.data[i].c < b.data[j].c)//比较非零数值所在的列数大小,将较小的列数非零数值放进c的三元组
			{
				c.data[k].r = a.data[i].r;
				c.data[k].c = a.data[i].c;
				c.data[k].d = a.data[i].d;
				i++;
				k++;
			}
			else if(a.data[i].c == b.data[j].c)//比较非零数值所在的列数大小,将两个非零元素相加的值放进c的三元组
			{
				c.data[k].r = b.data[j].r;
				c.data[k].c = b.data[j].c;
				c.data[k].d = a.data[i].d + b.data[j].d;
				i++;
				j++;
				k++;
			}
			else							//比较非零数值所在的列数大小,将较小的列数非零数值放进c的三元组
			{
				c.data[k].r = b.data[j].r;
				c.data[k].c = b.data[j].c;
				c.data[k].d = b.data[j].d;
				j++;
				k++;
			}
		}
		else							//比较非零数值所在的行数大小,将较小的行数数非零数值放进c的三元组
		{
			c.data[k].r = b.data[j].r;
			c.data[k].c = b.data[j].c;
			c.data[k].d = b.data[j].d;
			j++;
			k++;
		}
	}
	c.nums = k;//非零元素个数
}

//返回三元组 t 表示的 A[i][j]值
int getvalue(TSMatrix t,int i,int j)
{
	for(int k = 0; k < t.nums; k++)
	{
		if(t.data[k].r == i && t.data[k].c == j)
			return t.data[k].d;
	}
	return 0;
}

//两个稀疏矩阵相乘后对应的三元组
void MatMul(TSMatrix a,TSMatrix b,TSMatrix &c)
{
	if(a.cols != b.row)									//判断是否满足两矩阵相乘的条件,即第一个矩阵的列数与第二矩阵的行数相等
	{
		printf("矩阵相乘操作失败\n");
		return;
	}
	int i, j, k = 0, s;
	c.row = a.row;
	c.cols = b.cols;
	
	for(i = 0; i < a.row; i++)							//控制行数
	{
		for(j = 0; j < b.cols; j++)						//控制列数
		{
			s = 0;
			for(int m = 0; m < b.cols; m++)
			{
				s = s + getvalue(a, m, i)*getvalue(b, j, m);//第一个矩阵行的每个元素与第二个矩阵列的每个元素相乘,并将结果相加
			}
			if(s != 0)										//如果数据元素不为0,则将其放进c三元组中
			{
				c.data[k].r = i;
				c.data[k].c = j;
				c.data[k].d = s;
				k++;
			}
		}
	}
	c.nums = k;												//总非零元素个数
}

int main()
{
	TSMatrix t1, t2, c;			//t1, t2为三元组
	elem a[4][4] = {
		{1,0,3,0},
		{0,1,0,0},
		{0,0,1,0},
		{0,0,1,1}};
	CreatMat(t1, a);			//生成稀疏矩阵A三元组
	printf("a的三元组:\n");
	DipMat(t1);					//输出三元组
	elem b[4][4] = {
		{3,0,0,0},
		{0,4,0,0},
		{0,0,1,0},
		{0,0,0,2}};
	CreatMat(t2, b);			//生成稀疏矩阵B三元组
	printf("b的三元组:\n");
	DipMat(t2);					//输出三元组
	TranTat(t1, c);				//三元组转置
	printf("a转置后\n");
	DipMat(c);					//输出三元组
	printf("c = a + b\nc的三元组:\n");
	MatAdd(t1, t2, c);			//计算两个稀疏矩阵相加后对应的三元组
	DipMat(c);					//输出三元组
	printf("c = a * b\nc的三元组:\n");
	MatMul(t1, t2, c);			//矩阵相乘
	DipMat(c);					//输出三元组
	return 0;
}

四、运行结果截图

在这里插入图片描述

在这里插入图片描述

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值