创建稀疏矩阵并转置-C

1- 创建一个稀疏矩阵的前置要求

采用三元组来表示矩阵,每一个三元组对应存储三个要素信息,行值,列值和数值,三元组方式存储稀疏矩阵必须满足:非0数值的三元组,按行升值排序,行值相同按列值升序排列
需要两个结构体来确定最终形成的稀疏矩阵
进行的操作依次是:初始化,录入,打印,销毁,转置

每个三元组的组成内容
typedef struct TRIPLR_ELEMENT {
	int data;
	int row;
	int col;
}TRIPLR_ELEMENT;
最终形成的稀疏矩阵所需内容
typedef struct TRIPLE_MATRIX {
	TRIPLR_ELEMENT *elementList;
	int maxRow;
	int maxCol;
	int element;
}TRIPLE_MATRIX;
2- 创建一个稀疏矩阵

初始化:

TRIPLE_MATRIX *initTripleMatrix(int maxRow, int maxCol, int elementCount) {

	TRIPLE_MATRIX *result = NULL;

	result = (TRIPLE_MATRIX *)calloc(sizeof(TRIPLE_MATRIX), 1);
	//申请一个控制头
	result->elementList = (TRIPLR_ELEMENT *)
	                        calloc(sizeof(TRIPLR_ELEMENT), elementCount);
	//申请elementCount个TRIPLE_ELEMENT类型的元素
	result->maxRow = maxRow;
	result->maxCol = maxCol;
	result->elementCount = elementCount;
}

在这里插入图片描述

录入元素:

void inputTripleMatrix(const TRIPLE_MATRIX *matrix) {
//形参中使用const无可厚非, 因为真正改变的数值是elementList中的数值
//而不是类型为TRIPLE_MATRIX类型的matrix中的四个值,elementList只是
//一个数组名,指向某处空间的指针
	int index = 0;
	int count = matrix->elementCount;
	int row;
	int col;
	int data;

	printf("输入%d个非0元素的三元组:\n", count);

	for(index = 0; index < count; index++) {
		printf("第%d %d 个元素\n", index+1, count);
		scanf("%d%d%d", &row, &col, &data);
		matrix->elementList[index].row = row;
		matrix->elementList[index].col = col;
		matrix->elementList[index].data = data;
	}
}

打印稀疏矩阵:

void showTripleMatrix(const TRIPLE_MATRIX *matrix) {
//按行升序遍历出一个maxRow * maxCol的表,每打印完一行换行,
//遇到elementList中出现的行列坐标,如果匹配则在此处打印它的值,
//如果没有,则打印0

	int row;
	int col;
	int index = 0;
	
	for(row = 0; row < matrix->maxRow; row++) {
		for(col = 0; col < matrix->maxCol; col++) {
			if(row == matrix->elementList[index].row
				    && col == matrix->elementList[index].col) {

				printf("%4d", matrix->elementList[index].data);
			    index++;
			}else {
				printf("%4d", 0);
			}
		}
		printf("\n");
	}
}

销毁:

void destoryTripleMatrix(TRIPLE_MATRIX *matrix) {
	free(matrix->elementList);
	free(matrix);
}
3- 对稀疏矩阵完成转置

完成转置最简单的方法是,交换行列值,这样可以很快的完成,但是却打乱了三元组中数据按行升序的要求,在不使用排序的情况下,完成对稀疏矩阵的转置且三元组仍按行升序排列

输入数据示例(按行升序):

6 8 10
maxRow, maxCol, elementCount
1 0 1
1 6 2
3 2 3
3 6 4
4 0 5
4 4 6
5 1 7
5 3 8
5 5 9
5 7 10

原矩阵:

转置后矩阵:
在这里插入图片描述
转置后数据按行升序排列:

(0, 1) 1
(0, 4) 5
(1, 5) 7
(2, 3) 3
(3, 5) 8
(4, 4) 6
(5, 5) 9
(6, 1) 2
(6, 3) 4
(7, 5) 10 

第一步 先统计转置后,同一行的元素的个数分别是多少
在这里插入图片描述

TRIPLE_MATRIX *revTripleMatrix(const TRIPLE_MATRIX *matrix) {
	int *indexArr = NULL;
	int i = 0;
	int index;
	int colIndex;
	TRIPLE_MATRIX *result = NULL;

	indexArr = (int *) calloc(sizeof(int), matrix->maxCol + 1);
	for (index = 0; index < matrix->elementCount; index++) {
		indexArr[matrix->elementList[index].col + 1]++;
	}
	for (index = 1; index < matrix->maxCol + 1; index++) {
		indexArr[index] += indexArr[index - 1];
	}

	result = initTripleMatrix(matrix->maxCol, 
	         matrix->maxRow, matrix->elementCount);
//申请result交换行列下标, 值不变
	for (index = 0; index < matrix->elementCount; index++) {
		colIndex = matrix->elementList[index].col;
		
		result->elementList[indexArr[colIndex]].row
		 = matrix->elementList[index].col;
		 
		result->elementList[indexArr[colIndex]].col
		 = matrix->elementList[index].row;
		 
		result->elementList[indexArr[colIndex]].data
		 = matrix->elementList[index].data;
		 
		indexArr[colIndex]++;
	}
	return result;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值