稀疏矩阵如图所示,4行7列的矩阵一共28个元素,但是非零元素仅仅有5个。为了节省存储空间,实际上我们只需要存储这5个元素即可。
稀疏矩阵的存储一共有三种方式:
1.三元组顺序表方式存储。
2.行逻辑链接的顺序表。
3.十字链表法。
这篇是三元组顺序表方式存储的代码实现。
代码实现以及测试结果:
#include<stdio.h>
#include<stdlib.h>
/*
稀疏矩阵的三元组顺序表存储方式
*/
#define MaxSize 20 //该稀疏矩阵中有效元素的个数最大为20个
#define N 4 //N是矩阵的行数
#define M 7 //M是矩阵的列数
typedef struct {
int q,w; //q行标 w 列标
int value; //对应的元素值
}triple;
typedef struct {
triple data[MaxSize];
int n,m; //n,m是稀疏矩阵的行数和列数。
int length; //data中真实有效的元素个数, 初始时为0
}TSMatrix;
//矩阵的展示。
void disPlay(TSMatrix matix){
//此处的i j 分别是行标 列标
for(int i=1; i<=matix.n;i++){
for(int j=1;j<=matix.m;j++){
int flag = 0;
for(int x = 0;x<matix.length;x++){
if(i == matix.data[x].q && j==matix.data[x].w){
printf("%d ",matix.data[x].value);
flag = 1;
break;
}
}
//没找着的话,这个位置上输出0
if(flag == 0){
printf("0 ");
}
}
printf("\n");
}
}
//通过行标列表获取稀疏矩阵中的元素值
int getValue(TSMatrix matix,int i,int j){
for(int x = 0;x<matix.length;x++){
if(i==matix.data[x].q && j ==matix.data[x].w){
return matix.data[x].value;
}
}
//未找到返回0
return 0;
}
int main(int argc, char *argv[])
{
//用二维数组模拟一个稀疏矩阵
int matrix[N][M] ={
{0,0,0,1,0,0,0},
{0,2,0,0,0,0,0},
{0,0,0,0,0,3,0},
{4,0,0,5,0,0,0}
};
//这是在栈空间中开辟一个结构体存储空间。
TSMatrix tSMatrix;
tSMatrix.length=0;
//遍历二维数组存储非零元素
for(int i = 0; i < N;i++){
for(int j = 0; j < M ;j++){
if(matrix[i][j]!=0){
//行标列表都是从1开始的,存储的时候要加1
tSMatrix.data[tSMatrix.length].q=(i+1);
tSMatrix.data[tSMatrix.length].w=(j+1);
tSMatrix.data[tSMatrix.length].value = matrix[i][j];
tSMatrix.length++;
}
}
}
//元素存完了,再把矩阵的行数,列数存入结构体中。
tSMatrix.n=N;
tSMatrix.m=M;
//打印输出三元组顺序表中的元素
for(int i = 0 ;i<tSMatrix.length;i++){
printf("行标%d\t",tSMatrix.data[i].q);
printf("列标%d\t",tSMatrix.data[i].w);
printf("值%d\n",tSMatrix.data[i].value);
}
//把矩阵的行数、列数输出
printf("矩阵的行数为%d\n",tSMatrix.n);
printf("矩阵的列数为%d\n",tSMatrix.m);
printf("\n");
//矩阵的效果展示
disPlay(tSMatrix);
//输入行标列表获取稀疏矩阵中的元素值
int value = getValue(tSMatrix,3,6);
printf("第三行第六列的元素值为%d\n",value);
int value1 = getValue(tSMatrix,4,6);
printf("第四行第六列的元素值为%d\n",value1);
return 0;
}
三元组顺序表的方式存储稀疏矩阵的缺点:
当稀疏矩阵的数据全部存储到三元组顺序表之后,虽然节省了存储空间。但是访问矩阵元素的效率却降低了。
每当需要获取矩阵中的一个元素时,都需要把数组中所有的非零元素全部遍历一遍。加个break还好点,没那么夸张。
所以稀疏矩阵的三元组顺序表存储方式虽然空间复杂度下来了,但是时间复杂度上去了。
如果矩阵特别大,非零元素的个数特别少。可以采用这种存储方案。