当前位置:文档之家› 稀疏矩阵(算法与数据结构课程设计)

稀疏矩阵(算法与数据结构课程设计)

稀疏矩阵一、问题描述假若在n m ⨯阶中,有t 个元素不为零,令nm t ⨯=δ称为矩阵的稀疏因子。

通常认为≤δ0.05时称为稀疏矩阵。

稀疏矩阵的研究大大的减少了数据在计算机中存储所需的空间,然而,它们的运算却与普通矩阵有所差异。

通过本次实验实现稀疏矩阵的转置、加法和乘法等多种运算。

二、基本要求1、稀疏矩阵采用三元组表示,建立稀疏矩阵,并能按矩阵和三元组方式输出;2、编写算法,完成稀疏矩阵的转置操作;3、编写算法,完成对两个具有相同行列数的稀疏矩阵进行求和操作;4、编写算法,对前一矩阵行数与后一矩阵列数相等的两个矩阵,完成两个稀疏矩阵的相乘操作。

三、测试数据1、转置操作的测试数据:⎪⎪⎪⎪⎪⎭⎫ ⎝⎛00200013000010020100 2、相加操作的测试数据: ⎪⎪⎪⎪⎪⎭⎫ ⎝⎛00200013000010020100 ⎪⎪⎪⎪⎪⎭⎫ ⎝⎛00200010000210030300 3、相乘操作的测试数据: ⎪⎪⎪⎪⎪⎭⎫ ⎝⎛0000000300400021 ⎪⎪⎪⎪⎪⎭⎫ ⎝⎛001002000021 四、算法思想1、三元组结构类型为Triple ,用i 表示元素的行,j 表示元素的列,e 表示元素值。

稀疏矩阵的结构类型为TSMatrix ,用数组data[]表示三元组,mu 表示行数,nu 表示列数,tu 表示非零元个数。

2、稀疏矩阵转置的算法思想将需要转置的矩阵a 所有元素存储在三元组表a.data 中,按照矩阵a 的列序来转置。

为了找到a的每一列中所有非零元素,需要对其三元组表a.data扫描一遍,由于a.data 是以a的行需序为主序来存放每个非零元的,由此得到的就是a的转置矩阵的三元组表,将其储存在b.data中。

3、稀疏矩阵相加的算法思想比较满足条件(行数及列数都相同的两个矩阵)的两个稀疏矩阵中不为0的元素的行数及列数(即i与j),将i与j都相等的前后两个元素值e相加,保持i,j不变储存在新的三元组中,不等的则分别储存在此新三元组中。

最后得到的这个新三元组表就是两个矩阵的和矩阵的三元组表。

4、稀疏矩阵相乘的算法思想两个相乘的矩阵为M与N,对M中每个元素M.data[p](p=1,2,…,M.tu),找到N中所有满足条件M.data[p].j=N.data[q].i的元素N.data[q],求得M.data[p].v和N.data[q].v 的乘积,又T(i,j)=∑M(i,k)×N(k,j),乘积矩阵T中每个元素的值是个累计和,这个乘积M.data[p].v×N.data[q].v只是T[i][j]中的一部分。

为便于操作,应对每个元素设一累计和的变量,其初值是零,然后扫描数组M,求得相应元素的乘积并累加到适当的求累计和的变量上。

由于T中元素的行号和M中元素的行号一致,又M中元素排列是以M的行序为主序的,由此可对T进行逐行处理,先求得累计求和的中间结果(T的一行),然后再压缩存储到Q.data中去。

五、模块划分1、Status CreateM(TSMatrix *M, int a[],int row, int col),创立三元组;2、void PrintM(TSMatrix M),按数组方式输出;3、void PrintM3(TSMatrix M),按三元组方式输出;4、Status TransposeSMatrix(TSMatrix M, TSMatrix *T),稀疏矩阵的转置;5、Status MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix *Q),稀疏矩阵加法;6、Status MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix *Q),稀疏矩阵相乘;7、main(),主函数。

六、数据结构//(ADT)1、三元组结构类型typedef struct{ int i,j;ElemType e;} Triple;2、稀疏矩阵typedef struct{ Triple data[MAXSIZE+1];int mu,nu,tu;} TSMatrix;七、源程序#include "stdio.h"#define OK 1#define TRUE 1#define FALSE 0typedef int Status;typedef int ElemType;/* 三元组顺序表的类型定义 */#define MAXSIZE 1000#define MAXRC 1000typedef struct{ int i,j;ElemType e;} Triple;typedef struct{ Triple data[MAXSIZE+1];int mu,nu,tu;} TSMatrix;/* 建立三元组表 */Status CreateM(TSMatrix *M, int a[],int row, int col){ int i,k=0;for(i=0;i<row*col;i++)if (a[i]!=0){++k;(*M).data[k].i=i/col+1;(*M).data[k].j=i%col+1;(*M).data[k].e=a[i];}if (k){ (*M).tu=k; (*M).mu=row; (*M).nu=col; return TRUE; } elsereturn FALSE;}/* 按数组方式输出三元组表 */void PrintM(TSMatrix M){int k=1,p=1,n;printf("\nM:\n");if (M.tu){n=(M.data[p].i-1)*M.nu+M.data[p].j;for(k=1;k<=M.mu*M.nu;k++){if (k<n||k>n)printf(" 0");else{printf("%3d",M.data[p].e);p++;if (p<=M.tu) n=(M.data[p].i-1)*M.nu+M.data[p].j;}if (k%M.nu==0) printf("\n");}}}/* 按三元组方式输出三元组表 */void PrintM3(TSMatrix M){int k;printf("\nM3:");printf("\n i j e");for(k=1;k<=M.tu;k++)printf("\n%3d%3d%3d",M.data[k].i,M.data[k].j,M.data[k].e); }/*稀疏矩阵的转置*/Status TransposeSMatrix(TSMatrix M, TSMatrix *T){int q,col,p;(*T).mu=M.nu; (*T).nu=M.mu; (*T).tu=M.tu;if ((*T).tu){ q=1;for(col=1; col<=M.nu; ++col)for(p=1; p<=M.tu; ++p)if (M.data[p].j==col){ (*T).data[q].i=M.data[p].j;(*T).data[q].j=M.data[p].i;(*T).data[q].e=M.data[p].e;++q; }}return OK;}/*矩阵加法*/Status ContactM(TSMatrix M, TSMatrix N, TSMatrix *Q){ int k1,k2,k3=1,m,n;(*Q).mu=M.mu;(*Q).nu=M.nu;(*Q).tu=0;if(M.mu==N.mu && M.nu==N.nu){ for(k1=1;k1<=M.tu;k1++)for(k2=1;k2<=N.tu;k2++){if(M.data[k1].i==N.data[k2].i && M.data[k1].j==N.data[k2].j){ (*Q).data[k3].e=M.data[k1].e+N.data[k2].e;(*Q).data[k3].i=M.data[k1].i ;(*Q).data[k3].j=M.data[k1].j ; M.data[k1].e=0; N.data[k2].e=0;++k3;}m=k3; n=M.tu+N.tu;}k2=1;k1=1;for(k3=m;k3<n-5;k3++){ if(M.data[k1].e==0 || N.data[k2].e==0){k1++;k2++;k3--;}else{(*Q).data[k3].e=M.data[k1].e;(*Q).data[k3].i=M.data[k1].i ;(*Q).data[k3].j=M.data[k1].j;k1++;k3++;(*Q).data[k3].e=N.data[k2].e;(*Q).data[k3].i=N.data[k2].i ;(*Q).data[k3].j=N.data[k2].j ;k2++;}}}(*Q).tu=k3-1;}/*矩阵乘法*/Status MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix *Q){ int k1,k2,k3,m;(*Q).mu=M.mu;(*Q).nu=N.nu;(*Q).tu=0;if(M.nu==N.mu){ for(k1=1;k1<=M.tu;k1++)for(k2=1;k2<=N.tu;k2++){ if(M.data[k1].j==N.data[k2].i){ m=M.data[k1].e*N.data[k2].e;if((*Q).tu==0){(*Q).data[1].e=m;(*Q).data[1].i=M.data[k1].i;(*Q).data[1].j=N.data[k2].j;(*Q).tu++; }else{ for(k3=1;k3<=(*Q).tu;k3++){ if((*Q).data[k3].i==M.data[k1].i&&(*Q).data[k3].j==N.data[k2].j){ (*Q).data[k3].e+=m;break; }}if(k3==(*Q).tu+1){(*Q).data[k3].e=m;(*Q).data[k3].i=M.data[k1].i;(*Q).data[k3].j=N.data[k2].j;(*Q).tu++; }}}}}}/* 主函数 */main(){ int a[4][5]={0,0,1,0,2,0,0,1,0,0,0,0,3,1,0,0,0,2,0,0, },b[4][5]={ 0,0,3,0,3,0,0,1,2,0,0,0,0,1,0,0,0,2,0,0,},c[3][4]={1,2,0,0,0,4,0,0,3,0,0,0 },d[4][3]={1,2,0,0,0,0,2,0,0,1,0,0};TSMatrix M,N,Q,T,H,A,B;CreateM(&M,*c,3,4); CreateM(&N,*d,4,3);CreateM(&A,*a,4,5); CreateM(&B,*b,4,5);printf("\n矩阵相乘的第一个矩阵:");PrintM(M);printf("\n矩阵相乘的第二个矩阵:");PrintM(N);printf("\n矩阵相乘得到的矩阵:");MultSMatrix(M,N,&Q);printf("\n按矩阵方式输出:");PrintM(Q);printf("\n按三元组方式输出:");PrintM3(Q);printf("\n矩阵相加的第一个矩阵:");PrintM(A);printf("\n矩阵相加的第二个矩阵:");PrintM(B);ContactM(A,B,&H);printf("\n两个矩阵的和矩阵为:");PrintM3(H);printf("\n被转置的矩阵:");PrintM(A);TransposeSMatrix(A,&T);printf("\n矩阵的转置矩阵为:");PrintM(T);}八、测试情况程序的测试结果如下1、矩阵转置2、矩阵相加3、矩阵相乘九、参考文献1、严蔚敏,《数据结构 C语言》,清华大学出版社。

相关主题