顺序表练习(二):稀疏矩阵的三元组压缩储存及其简单运算实现

前言

这次依旧是数据结构的作业题,先看一下作业的要求:

  • 以三元组的形式压缩储存稀疏矩阵
  • 实现矩阵的转置、加法、乘法运算

稀疏矩阵指的是矩阵中大多数的元素是0,而且非0元素的分布没有规律的矩阵。而这个三元组其实就是指这样的结构体的数组:

typedef struct TupNode
{
	int r; //行号
	int c; //列号
	int data;//数据
} Tup;

整个的数据结构定义如下:

#define M 5
#define N 5
#define MAXSIZE 25

typedef struct TupNode
{
	int r;
	int c;
	int data;
} Tup;

typedef struct TSMatrix
{
	int rows;//整个矩阵的行数
	int cols;//整个矩阵的列树
	int nums;//三元组中储存的元素个数,其实就代表着矩阵中的非零元素个数
	TupNode arr[MAXSIZE];//三元组本体
} Mat;

这个Mat就是我们将稀疏矩阵压缩后的三元组数据结构,为了方便,这里直接统一矩阵为5*5方阵。

 

先实现一些辅助函数

先实现创建三元组对象的create函数、输出三元组的print函数、销毁三元组的destroy函数:

Mat *createMat(int (&a)[M][N])//根据传进来的二维数组引用创建三元组
{
	Mat *mat = new Mat;
	int i, j;
	mat->cols = N;
	mat->rows = M;
	mat->nums = 0;
	for (i = 0; i < M; i++)
	{
		for (j = 0; j < N; j++)
		{
			if (a[i][j] != 0)
			{
				mat->arr[mat->nums].r = i;
				mat->arr[mat->nums].c = j;
				mat->arr[mat->nums].data = a[i][j];
				mat->nums++;
			}
		}
	}
	return mat;
}

Mat *createMat(Mat *mat)//根据传进来的三元组创建三元组的拷贝,若传NULL,则返回空三元组
{
	Mat *res = new Mat;
	res->cols = N;
	res->rows = M;
	res->nums = 0;
	if (mat)
		*res = *mat;
	return res;
}

void print(Mat *mat)//输出整个矩阵
{
	int cur = 0;
	for (int i = 0; i < M; i++)
	{
		for (int j = 0; j < N; j++)
		{
			cur = 0;
			for (int k = 0; k < mat->nums; k++)
			{
				if (mat->arr[k].r == i && mat->arr[k].c == j)
				{
					cur = mat->arr[k].data;
				}
			}
			cout << cur << " ";
		}
		cout << endl;
	}
	cout << endl;
}

void printTup(Mat *mat)//以三元组形式输出,并输出对应数组下标
{
	for (int i = 0; i < mat->nums; i++)
	{
		cout << i << "(" << mat->arr[i].r << "," << mat->arr[i].c << "," << mat->arr[i].data << ") ";
	}
	cout << endl;
}

void destroy(Mat *mat)//销毁三元组
{
	delete mat;
}

csdn的缩进比较迷,如果实在看不了可以复制到ide里看,我是用vscode写的。

 

矩阵的转置

原理比较简单,其实就是将矩阵的每个元素的行号和列号互换就可以了,但是用三元组储存的话需要多考虑一些问题:

  1. 首先要明确的就是,矩阵的转置不会改变矩阵里元素的值,那么矩阵里非零元素的个数也不会改变,0还是0,非0元素转置后还是非0元素。所以我们不需要增删三元组的元素。
  2. 其次,三元组的储存是根据行号和列号顺序储存的,如果我们只是简单地写个for交换每个元素的行列,这样三元组的顺序会被打乱,虽说还原后还是一样能得到正确的矩阵,但是这样不利于我们后面写查找算法。所以我们需要在交换完行列以后再对三元组进行排序。

实现代码:

void insertionSortMat(Tup (&arr)[MAXSIZE], int n)//三元组的插入排序
{
    	Tup tmp;
    	for (int i = 1; i < n; i++)
	{
       		tmp = arr[i];
    		int j;
                //注意for的条件
    		for (j = i; j > 0 && arr[j - 1].r > tmp.r && arr[j - 1].c > tmp.c; j--)
    		{
    			arr[j] = arr[j - 1];
    		}
		arr[j] = tmp;
    	}
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值