signed

QiShunwang

“诚信为本、客户至上”

稀疏矩阵sparse Matrix的顺序表存储,c/c++描述

2021/6/3 16:17:34   来源:

  稀疏二维矩阵里大量的0,少量的非0数值,所以存储时可以考虑只存储非0值。顺序表里存储的是结构体变量,每个结构体包含了非0元素的行列下标和元素值三方面的信息。必不可少的两个函数是建立顺序表savingArray,方向是从矩阵到顺序表;再一个是从顺序表中读取矩阵元素值getValue,至于矩阵加法,尤其是矩阵乘法的特殊性,为了矩阵元素计算的不重不漏,并不能因为是稀疏矩阵而减少算法的次数,但对于转置矩阵,考虑了基于稀疏矩阵的特殊算法,但本算法本身的时间复杂度是比较大的。
  每道例题,我都保存在csdn里,因为这数据结构的课本看起来实在太痛苦,不这么做,不足以平慰心中之恨。而且,文里改写后的程序阅读体验更佳,更容易理解。

#include<iostream>
#include<stdio.h>
using namespace std;
#define MAXSIZE 100
#define RANK 4   //数组幅度,指数组大小
#define COLUMN 4
struct Element {
	int rank;
	int column;
	int value;
};
struct SequenSaving {
	int rankTotal;
	int columnTotal;
	int numbTotal;
	Element elements[MAXSIZE];
};

int getValue(SequenSaving& seqnenSaving, int rank, int column) {
	int kNumber;
	//find this element by rank
	for (kNumber = 0; kNumber < seqnenSaving.numbTotal; kNumber++)
		if (seqnenSaving.elements[kNumber].rank == rank &&
			seqnenSaving.elements[kNumber].column == column)
			return seqnenSaving.elements[kNumber].value;
		else if (seqnenSaving.elements[kNumber].rank > rank)
			return 0;
	return 0;
}
void savingArray(int array[RANK][COLUMN], SequenSaving& sequenSaving) {
	sequenSaving.columnTotal = COLUMN;
	sequenSaving.rankTotal = RANK;
	sequenSaving.numbTotal = 0;
	for (int rank = 0; rank < RANK; rank++)
		for (int column = 0; column < COLUMN; column++)
			if (array[rank][column] != 0) {
				sequenSaving.elements[sequenSaving.numbTotal].rank = rank;
				sequenSaving.elements[sequenSaving.numbTotal].column = column;
				sequenSaving.elements[sequenSaving.numbTotal].value = array[rank][column];
				sequenSaving.numbTotal++;
			}
}

void dispalyArray(SequenSaving &sequenSaving) {
	int i, j, k;
	for (i = 0; i < sequenSaving.rankTotal; i++) {
		for (j = 0; j < sequenSaving.columnTotal; j++) {
			k = getValue(sequenSaving, i, j);
			if (k != 0)
				printf("%5d", k);
			else
				printf("%5d", 0);
		}
		cout << endl << endl;
	}
}

void addArray(SequenSaving &sequenSavingA, SequenSaving &sequenSavingB,
	SequenSaving &sequenSavingAdd) {
	int array[RANK][COLUMN];
	for (int i = 0; i < RANK; i++)
		for (int j = 0; j < COLUMN; j++)
			array[i][j] = getValue(sequenSavingA, i, j) + 
						getValue(sequenSavingB,i,j);
	savingArray(array,sequenSavingAdd);
}
void multipArray(SequenSaving &sequenSavingA, SequenSaving &sequenSavingB,
	SequenSaving &sequenSavingMultip) {
	int rank, column, i;
	int array[RANK][COLUMN];
	for(rank = 0 ; rank < RANK ; rank++)
		for (column = 0; column < COLUMN; column++) {
			array[rank][column] = 0;
			for (i = 0; i < COLUMN; i++)
				array[rank][column] += getValue(sequenSavingA, rank, i) *
						getValue(sequenSavingB,i,column);
		}
	savingArray(array,sequenSavingMultip);
}
void transposion(SequenSaving &sequenSavingFrom, SequenSaving &sequenSavingTo) {
/*	int array[COLUMN][RANK];      注释的方法也对,逻辑很简单
	for (int rank = 0; rank < COLUMN; rank++)
		for (int column = 0; column < RANK; column++)
			array[rank][column] = getValue(sequenSavingFrom,column,rank);
	savingArray(array,sequenSavingTo);
*/
	int rank, column;  //they belong to the arrayFrom   ,这是课本里的方法
	sequenSavingTo.numbTotal = 0;
	sequenSavingTo.rankTotal = sequenSavingFrom.columnTotal;
	sequenSavingTo.columnTotal = sequenSavingTo.rankTotal;
	
	//原矩阵按列查找,相当于新矩阵按行存储
	for(column =0 ; column < COLUMN ; column++)
		for(rank = 0 ; rank < RANK ; rank++)
			for(int i = 0; i < sequenSavingFrom.numbTotal ; i++)
				if (column == sequenSavingFrom.elements[i].column &&
					rank == sequenSavingFrom.elements[i].rank) {
					sequenSavingTo.elements[sequenSavingTo.numbTotal].rank = column;
					sequenSavingTo.elements[sequenSavingTo.numbTotal].column = rank;
					sequenSavingTo.elements[sequenSavingTo.numbTotal].value =
						sequenSavingFrom.elements[i].value;
					
					sequenSavingTo.numbTotal++;
				}
}

int main() {
	int arrayA[][COLUMN] = { {1,0,3,0},{0,1,0,0},{0,0,1,0},{0,0,1,1} };
	int arrayB[][COLUMN] = { {3,0,0,0},{0,4,0,0},{0,0,1,0},{0,0,0,2} };

	SequenSaving sequenSavingA, sequenSavingB,sequenSavingAdd,sequenSavingMultip;
	SequenSaving sequenSavingTranspoA;

	savingArray(arrayA,sequenSavingA);
	savingArray(arrayB,sequenSavingB);

	cout << "arrayA :" << endl;
	dispalyArray(sequenSavingA);

	cout << endl << "arrayB : " << endl;
	dispalyArray(sequenSavingB);

	addArray(sequenSavingA,sequenSavingB,sequenSavingAdd);
	multipArray(sequenSavingA,sequenSavingB,sequenSavingMultip);

	cout << endl << "arrayAdd : " << endl;
	dispalyArray(sequenSavingAdd);

	cout << endl << "arrayMultip : " << endl;
	dispalyArray(sequenSavingMultip);

	transposion(sequenSavingA,sequenSavingTranspoA);

	cout << endl << "arrayTransposion : " << endl;
	dispalyArray(sequenSavingTranspoA);

	return 0;
}

测试结果如下:
在这里插入图片描述
在这里插入图片描述
经手工计算答案是正确的