稀疏二维矩阵里大量的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;
}
测试结果如下:
经手工计算答案是正确的