文章目录
稀疏矩阵的压缩存储,只存储矩阵的非0元。因此需要一个数组来表示稀疏矩阵非0元的值与行列值
基本操作有创建,销毁,打印与拷贝
代码实现部分
头文件部分
需要用到的头文件与三元组的定义
这里我将DEBUG注释掉了,没注释之前是用来调试程序的
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#define OK 1
#define ERROR 0
#define MAXSIZE 12500 //假设非0元个数的最大值为12500
//#define DEBUG
typedef int Status;
//三元组稀疏矩阵类型定义
typedef int ElemType;
typedef struct {
int i, j; //该非0元的行标与列表
ElemType e; //该非0元的值
}Triple;
typedef struct {
Triple data[MAXSIZE + 1]; //非0元素的三维组表,data[0]未用
int mu, nu, tu; //矩阵的行列数与非0元素个数
}TSMatrix;
创建稀疏矩阵部分
创建稀疏矩阵可以分为两种形式,一种是文件形式,使用stadrg头文件实现可变参数可以一次性读取多个稀疏矩阵,也可以通过在stdin输入的形式来创建稀疏矩阵
文件形式创建稀疏矩阵
#ifdef用来调试,程序段里有多个#ifdef,懒得删了
fscanf函数用来将文件中的数字读取到三个变量中
先读取的是矩阵的行列与非0元数,再读取的是非0元所在行列与值
Status CreatSmatrix1(FILE* fp, int n, ...)
{
int count;
int k;
TSMatrix *M;
if (n < 1)
return ERROR;
va_list ap;
va_start(ap, n);
for (count = 1; count <= n; count++)
{
M = va_arg(ap, TSMatrix*);
fscanf(fp, "%d %d %d", &(M->mu), &(M->nu), &(M->tu));
#ifdef DEBUG
printf("行列数和非0元数分别是%d %d %d\n", (M->mu), (M->nu), (M->tu));
#endif // DEBUG
for (k = 1; k <= M->tu; k++)
{
fscanf(fp, "%d %d %d", &(M->data[k].i), &(M->data[k].j), &(M->data[k]).e);
#ifdef DEBUG
printf("第%d个非0元的行列数以及值为%d %d %d\n", k, (M->data[k].i), (M->data[k].j), (M->data[k]).e);
#endif // DEBUG
}
}
va_end(ap);
return OK;
}
通过输入形式创建稀疏矩阵
Status CreatSmatrix2(TSMatrix* T)
{
printf("请输入矩阵的行和列:");
scanf("%d %d", &T->mu, &T->nu);
int value;
int k = 0;
for (int i = 1; i <= T->mu; i++)
{
for (int j = 1; j <= T->nu; j++)
{
scanf("%d", &value);
//如果此位置为非0元素,则将此元素记入三维数组
if (value != 0)
{
k++;
T->data[k].i = i;
T->data[k].j = j;
T->data[k].e = value;
}
}
}
T->tu = k;
return OK;
}
销毁稀疏矩阵
void DestroySMatrix(TSMatrix* M)
{
M->mu = 0;
M->nu = 0;
M->tu = 0;
}
稀疏矩阵的打印在这里插入代码片
void PrintSMatrix(TSMatrix M)
{
int r, d;
int k = 1;
for (r = 1; r <= M.mu; r++)
{
for (d = 1; d <= M.nu; d++)
{
if (r == M.data[k].i && d == M.data[k].j)
{
printf("%3d ", M.data[k].e);
k++;
}
else
printf(" 0 ");
}
puts("");
}
}
系数矩阵的拷贝
void CopySMatrix(TSMatrix M, TSMatrix* T)
{
*T = M;
//结构体可以直接复制
}
源程序部分
主要用来测试函数
#include "TripleSparseMatrix.h"
FILE* CreatFile( );
int main()
{
TSMatrix M,P,Q,U;
TSMatrix T;
TSMatrix N;
printf("测试函数CreatSmatrix1\n");
{
FILE* fp = CreatFile();
CreatSmatrix1(fp, 3, &M, &P, &U);
printf("打印稀疏矩阵M\n");
PrintSMatrix(M);
printf("打印稀疏矩阵P\n");
PrintSMatrix(P);
printf("打印稀疏矩阵U\n");
PrintSMatrix(U);
}
//不知道为什么两个输入函数不能一起测试将第一个输入函数注释掉第二个可正常运行
//printf("测试函数CreatSmatrix2\n");
//{
// CreatSmatrix2(&T);
// PrintSMatrix(T);
//}
printf("测试函数CopySMatrix\n");
{
CopySMatrix(M,&U);
PrintSMatrix(U);
}
printf("测试函数DestroySMatrix\n");
{
DestroySMatrix(&M);
PrintSMatrix(M);
printf("销毁成功\n");
}
return 0;
}
在文件中添加矩阵的函数
如果要添加矩阵,可以用a+的方式打开文件,在文件末尾添加,如果不用按#即可
我这里主函数中创建的是3个矩阵,你也可以自行改变矩阵个数,后面的变量个数也要改变
按照我的可以输入下列数字来检验
3 4 4
1 1 3
1 4 5
2 2 -1
3 1 2
3 4 5
1 2 1
1 4 4
2 1 1
2 2 1
2 3 2
4 2 4
1 2 2
2 1 1
3 1 -2
3 2 4
定义了一个三行四列有四个非0元的稀疏矩阵,一个3行四列5个非0元的稀疏矩阵和一个4行2列4个非0元的稀疏矩阵,这样定义是为了方便以后实现乘法和加法运算
FILE* CreatFile( )
{
FILE* fp;
int n;
//a+以读写的方式打开文件,可在文件末尾追加文本,若没有此文件则新建
if ((fp = fopen("345.txt", "a+")) == NULL)
{
fprintf(stdout, "Can't open\"wordy\"file.\n");
exit(EXIT_FAILURE);
}
puts("Enter words to add to the file; press the #");
puts("key at the beginning of a line to terminate.");
puts("先输入矩阵的行列数与非0元个数.");
while (scanf("%d", &n) == 1)
{
fprintf(fp, "%d", n);
fprintf(fp, " ");
}
puts("");
rewind(fp);
return fp;
}