(13)稀疏矩阵的压缩-三元组表(转置)

若矩阵中的非零元素远远小于矩阵元素的个数,且分布没有规律,则称这个矩阵为稀疏矩阵。
压缩存储是指对多个值相同的元素只分配一个存储空间,对零元素不分配空间。

稀疏矩阵的压缩存储有两种方法:三元组的顺序存储(三元组表)和链式存储(十字链表)。

现在主要讲三元组表,由于两个阶数不同的矩阵可能具有相同的非零元素,为了区别,在存储三元组时,同时还应存储该矩阵的行数、列数。通常为了运算的方便,也存放非零元素的个数。这种以顺序存储

结构来表示三元组的线性表,称之为三元组表。稀疏矩阵的存储的三元组表的存储结构可定义如下:

#define MAXSIZE 1000			//用户自定义三元组最大个数
typedef int ElemType;
typedef struct {				//三元组
	int row,col;				//非零元素的行数和列数
	ElemType e;					//非零元素的值
}Triple;
typedef struct {
	Triple data[MAXSIZE];		//三元组表
	int m,n, len;				//矩阵的行数、列数和非零个数
}TSMatrix;

(1)三元组表的矩阵转置运算-“直接取,顺序存”

//转置
TSMatrix TransTSMatrixSlow(TSMatrix a,TSMatrix b) {
	int q;
	b.m = a.n;
	b.n = a.m;
	b.len = a.len;
	if (b.len) {
		q = 0;							//B中的非零个数
		for (int j = 0; j < a.n;j++) {			//按列转置
			for (int h = 0; h < a.len; h++) {
				if (j==a.data[h].col) {			//本列中一个非零元素
					b.data[q].row = a.data[h].col;
					b.data[q].col = a.data[h].row;
					b.data[q].e = a.data[h].e;
					q++;
				}
			}
		}
	}
	else {
		cout << "矩阵为空,无需转置!" << endl;
	}
	return b;
}
但是每处理一列就要查遍三元组表,工作量比较大


(2)三元组表的矩阵快速转置运算-“顺序取,直接存”

//快速转置
TSMatrix TransTSMatrixFast(TSMatrix a, TSMatrix b) {
	int number[MAXSIZE],position[MAXSIZE];
	b.m = a.n;
	b.n = a.m;
	b.len = a.len;
	for (int j = 0; j < a.n;j++) {
		number[j] = 0;		//将矩阵a每一列非零元素的个数初始化为零
	}
	for (int t = 0; t < a.len; t++) {
		number[a.data[t].col]++;		//求每一列非零元素的个数
	}
	position[0] = 0;
	for (int j = 1; j < a.n; j++) {	//a.data[]的第j列第一个非零元素在b.data中的序号
		position[j] = position[j - 1] + number[j - 1];
	}
	int j,q;
	for (int p = 0; p < a.len; p++) {	//求转置矩阵b的三元组表
		j = a.data[p].col;
		q = position[j];
		b.data[q].row = a.data[p].col;
		b.data[q].col = a.data[p].row;
		b.data[q].e = a.data[p].e;
		position[j]++;
	}
	return b;
}
核心:若用number数组记录矩阵A中每列的非零元素个数,用position数组记录A中每列第一个非零元素在三元组表中的位置,则若第j-1列的第一个非零元素在position[j-1]的位置上,第j列的第一个非零元素必在第position[j-1]+number[j-1]位置上。


完整代码:

#include<iostream>
using namespace std;
#define MAXSIZE 1000			//用户自定义三元组最大个数
typedef int ElemType;
typedef struct {				//三元组
	int row,col;				//非零元素的行数和列数
	ElemType e;					//非零元素的值
}Triple;
typedef struct {
	Triple data[MAXSIZE];		//三元组表
	int m,n, len;				//矩阵的行数、列数和非零个数
}TSMatrix;
//输出矩阵
void print(TSMatrix a){
	int k;
	for (int i = 0; i < a.m;i++) {
		for (int j = 0; j < a.n;j++) {
			k = 0;
			for(int h=0;h<a.len;h++){
				if (i == a.data[h].row && j==a.data[h].col) {
					cout <<"     "<< a.data[h].e;
					k = 1;
				}
			}
			if (k == 0) {
				cout << "     " << k;
			}
		}
		cout << endl;
	}
}
//转置
TSMatrix TransTSMatrixSlow(TSMatrix a,TSMatrix b) {
	int q;
	b.m = a.n;
	b.n = a.m;
	b.len = a.len;
	if (b.len) {
		q = 0;							//B中的非零个数
		for (int j = 0; j < a.n;j++) {			//按列转置
			for (int h = 0; h < a.len; h++) {
				if (j==a.data[h].col) {			//本列中一个非零元素
					b.data[q].row = a.data[h].col;
					b.data[q].col = a.data[h].row;
					b.data[q].e = a.data[h].e;
					q++;
				}
			}
		}
	}
	else {
		cout << "矩阵为空,无需转置!" << endl;
	}
	return b;
}
//快速转置
TSMatrix TransTSMatrixFast(TSMatrix a, TSMatrix b) {
	int number[MAXSIZE],position[MAXSIZE];
	b.m = a.n;
	b.n = a.m;
	b.len = a.len;
	for (int j = 0; j < a.n;j++) {
		number[j] = 0;		//将矩阵a每一列非零元素的个数初始化为零
	}
	for (int t = 0; t < a.len; t++) {
		number[a.data[t].col]++;		//求每一列非零元素的个数
	}
	position[0] = 0;
	for (int j = 1; j < a.n; j++) {	//a.data[]的第j列第一个非零元素在b.data中的序号
		position[j] = position[j - 1] + number[j - 1];
	}
	int j,q;
	for (int p = 0; p < a.len; p++) {	//求转置矩阵b的三元组表
		j = a.data[p].col;
		q = position[j];
		b.data[q].row = a.data[p].col;
		b.data[q].col = a.data[p].row;
		b.data[q].e = a.data[p].e;
		position[j]++;
	}
	return b;
}
void main() {
	TSMatrix A, B;
	A.m = 5;
	A.n = 6;
	A.len = 7;
	A.data[0].row = 0; A.data[0].col = 1; A.data[0].e = 6;
	A.data[1].row = 0; A.data[1].col = 5; A.data[1].e = -2;
	A.data[2].row = 2; A.data[2].col = 3; A.data[2].e = -8;
	A.data[3].row = 3; A.data[3].col = 1; A.data[3].e = 3;
	A.data[4].row = 3; A.data[4].col = 5; A.data[4].e = 7;
	A.data[5].row = 4; A.data[5].col = 0; A.data[5].e = -12;
	A.data[6].row = 4; A.data[6].col = 2; A.data[6].e = 9;
	cout << "矩阵A为:" << endl;
	print(A);
	cout << "求系数矩阵A的转置矩阵B?" << endl;
	B = TransTSMatrixSlow(A,B);
	cout << "转置矩阵B为:" << endl;
	print(B);
	cout << endl;
	B = TransTSMatrixFast(A,B);
	print(B);
	system("pause");
}




  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值