稀疏矩阵的乘法实现程序:1# include <stdio.h>2# include <stdlib.h>3# define NULL 04# define OK 15# define ERROR 06# define MAXSIZE 100 /* 矩阵中非零元的最大值 */7# define MAXRC 10 /* 矩阵的最大行值 */89typedef int status ;1011 /********** 稀疏矩阵的行逻辑链接的顺序表存储表示 **********/1213typedef struct /* 非零元的三元组 */14{15int i, j ; /* 非零元的行下标和列下标 */16int e ;17}Triple;1819typedef struct /* 稀疏矩阵的行逻辑链接的顺序表 */20{21 Triple data[MAXSIZE+1]; /* 非零三元组表,data[0]未用,以下定义的数组都是从1开始 */22int rpos[MAXRC+1]; /* 代表各行第一个非零元的序号表,其值为data的下标 */23int mu,nu,tu; /* 矩阵的行数、列数、非零元的个数 */24}RLSMatrix; /* R:row L:logic S:sequence */252627 /********* 基本操作的函数原型的声明 *********/2829status CreateSMatrix_RL(RLSMatrix * matrix);30// 创建一个稀疏矩阵;31// 输入行数、列数,支持乱序输入三元组,并计数;32// 以行为主序进行重新排列,并记录每行起始位置于matrix->rpos[row];33// 若非零元超过 MAXSIZE或行数超过MAXRC,则返回ERROR,否则OK;3435void PrintSMatrix_RL(RLSMatrix * matrix);36// 输入矩阵,打印出矩阵的行数、列数、非零元个数,以及整个矩阵;3738status MultSMatrix_RL(RLSMatrix * M,RLSMatrix *N,RLSMatrix * Q);39// 输入两个稀疏矩阵M和N,并初始化Q,然后计算M*N的值赋给Q;40// 如果M->mu!=N->nu或列数大于MAXRC或者计算出的非零元个数大于MAXSIZE,都返回ERROR,否则OK;41// 计算过程如下:42// 1. 由于矩阵M和Q的行数相等并且C语言以行为主序进行存储,所以以M进行逐行的扫描。
43// 2. 使Q的此行逻辑表的序号等于其非零元个数Q.tu+1,以表示其行的首个元素的序号。
44// 3. 从行中找到M的非零元,并以它的列值为N的行号,对N 进行行的扫描,若存在,则依次计算它们,并把其值累加到一个以N中这个对应非零元的列值为序号的临时数组ctemp[ccol]中。
45// 4. 在M的当前行完成扫描后,将ctemp[ccol]不为0的值,压入到Q矩阵的三元组,累加++Q.tu,若Q.tu大于了MAXSIZE,这返回ERROR。
4647/************ main( ) 函数对矩阵乘法的实现 ************/ 4849void main()50{51 RLSMatrix * M,* N,* Q;52if(!(M=(RLSMatrix *)malloc(sizeof(RLSMatrix)))) 53 exit(ERROR);54if(!(N=(RLSMatrix *)malloc(sizeof(RLSMatrix))))55 exit(ERROR);56if(!(Q=(RLSMatrix *)malloc(sizeof(RLSMatrix))))57 exit(ERROR);58if(CreateSMatrix_RL(M)&&CreateSMatrix_RL(N))59 {60 printf("/nput out M:/n");61 PrintSMatrix_RL(M); /* 打印出M */62 printf("/nput out N:/n");63 PrintSMatrix_RL(N); /* 打印出N */64if(MultSMatrix_RL(M,N,Q)){66 printf("/n/n/n M * N :/n");67 PrintSMatrix_RL(Q); /* 计算结果*/68 }69else70 printf("M.mu and N.nu are not mathing/n");71 }72else73 printf("input error./n");74}757677/*********** 基本操作的算法描述 ****************/7879status CreateSMatrix_RL(RLSMatrix * matrix)80// 创建一个稀疏矩阵;81// 输入行数、列数,支持乱序输入三元组,并计数;82{83int num=0,p,q,min,temp; // 中间变量;84int row;85 printf("input the total row and col:/n");86 scanf("%d%d",&matrix->mu,&matrix->nu); //输入行数、列数;87if(matrix->mu>MAXRC)88return ERROR;89 printf("row col val/n");90scanf("%d%d%d",&matrix->data[num+1].i,&matrix->data[num+1].j,&matrix->data[num+1].e);91while(matrix->data[num+1].i) // 乱序输入三元组;92 {93if(++num>MAXSIZE)94return ERROR;95scanf("%d%d%d",&matrix->data[num+1].i,&matrix->data[num+1].j ,&matrix->data[num+1].e);96 }97 matrix->tu=num; // num的值即为此矩阵的非零元个数;98for(p=1;p<=matrix->tu-1;++p) // 按行为主序依次重新排列非零元99 {100 min=p; // 使较小的行数、列数的元的序号min为当前值p;101for(q=p+1;q<=matrix->tu;++q) // 开始依次比较;102 {103if(matrix->data[min].i>matrix->data[q].i||(matrix->data[min] .i==matrix->data[q].i&&matrix->data[min].j>matrix->data[q].j ))104 min=q; // 在乱序的三元表中,始终保证min是较小的行列数的序号;105 }106 temp=matrix->data[min].i; // 交换行值;matrix->data[min].i=matrix->data[p].i;108 matrix->data[p].i=temp;109 temp=matrix->data[min].j; // 交换列值;110 matrix->data[min].j=matrix->data[p].j;111 matrix->data[p].j=temp;112 temp=matrix->data[min].e; // 交换元素值;113 matrix->data[min].e=matrix->data[p].e;114 matrix->data[p].e=temp;115 }116for(row=1,num=0;row<=matrix->mu;++row) // 记录matrix->rpos[row];117 {118 matrix->rpos[row]=num+1;119while(matrix->data[num+1].i==row)120 ++num;121 }122return OK;123}124// 时间复杂度分析:125// 1. 输入非零元:O(tu); 2. 重新排列(最坏情况下);O(tu*(tu-1)) ; 3. 记录行逻辑表:O(mu)126void PrintSMatrix_RL(RLSMatrix * matrix)127// 输入矩阵,打印出矩阵的行数、列数、非零元个数,以及整个矩阵;128{129int row,col;130int num=0;131 printf("/nrow:%d col:%dnumber:%d/n",matrix->mu,matrix->nu,matrix->tu);132for(row=1;row<=matrix->mu;++row)133 {134for(col=1;col<=matrix->nu;++col)135 {136if(num+1<=matrix->tu&&matrix->data[num+1].i==row&&matrix->da ta[num+1].j==col)137 {138 ++num;139printf("%4d",matrix->data[num].e); /* 当扫描到非零元的行列值与之相等时,输出其值 */140 }141else142 printf("%4d",NULL); /* 没有非零元的地方补0 */143 }144 printf("/n"); /* 每行输入完毕后,换行 */145 }146}147148// 时间复杂度:O(mu*nu).149150151152status MultSMatrix_RL(RLSMatrix * M,RLSMatrix *N,RLSMatrix * Q)153// 输入两个稀疏矩阵M和N,并初始化Q,然后计算M*N的值赋给Q154{155int arow,brow,ccol;156int * ctemp; /* 以N的列值为序号的临时数组 */ 157int tp,p,tq,q; /* 中间变量 */158if(M->nu!=N->mu)159return ERROR;160 Q->mu=M->mu; /* 初始化Q */161 Q->nu=N->nu;162 Q->tu=0;163if(!(ctemp=(int *)malloc((N->nu+1)*sizeof(int)))) /* 动态建立累加器 */164 exit(ERROR);165if(M->tu*N->tu!=0) /* Q是非零矩阵*/166 {167for(arow=1;arow<=M->mu;++arow) /* 逐行扫描 */168 {169for(ccol=1;ccol<=N->nu;++ccol)170 ctemp[ccol]=0; /* 初始化累加器 */171 Q->rpos[arow]=Q->tu+1;172if(arow<M->mu)173 tp=M->rpos[arow+1]; /* tp是M下一行的序号 */174else175 tp=M->tu+1;176for(p=M->rpos[arow];p<tp;++p) /* 从M的当前行找到元素 */{178 brow=M->data[p].j; /* 对应元在N中的行号 */179if(brow<N->mu)180 tq=N->rpos[brow+1]; /* tq是N下一行的行号 */181else182 tq=N->tu+1;183for(q=N->rpos[brow];q<tq;++q) /* 以M的对应元的列号为N的行号进行扫描 */184 {185 ccol=N->data[q].j; /* 提取对应元的列号 */186ctemp[ccol]+=M->data[p].e*N->data[q].e;187 /* 两个对应元的值相乘并累加到以列号为序号的累加器中 */188 }189 }190for(ccol=1;ccol<=Q->nu;++ccol) /* 将此行非零元压缩入Q中 */191 {192if(ctemp[ccol])193 {194if(++Q->tu>MAXSIZE)195return ERROR;196 Q->data[Q->tu].i=arow; 197 Q->data[Q->tu].j=ccol; 198Q->data[Q->tu].e=ctemp[ccol];}200 }201 }202 }203return OK;204}205// 时间复杂度:O(M->mu*(N->nu+M->nu*N->nu+N->nu));status CreateSMatrix_RL(RLSMatrix * matrix)这个函数用2种算法进行了编写:第一种不支持乱序输入,而且输入很麻烦。