稀疏矩阵的乘法实现Word格式.docx
《稀疏矩阵的乘法实现Word格式.docx》由会员分享,可在线阅读,更多相关《稀疏矩阵的乘法实现Word格式.docx(8页珍藏版)》请在冰豆网上搜索。
![稀疏矩阵的乘法实现Word格式.docx](https://file1.bdocx.com/fileroot1/2022-12/14/060586a7-6883-4403-9caa-0a514fe7b74a/060586a7-6883-4403-9caa-0a514fe7b74a1.gif)
25
26
27/*********基本操作的函数原型的声明*********/
28
29statusCreateSMatrix_RL(RLSMatrix*matrix);
30//创建一个稀疏矩阵;
31//输入行数、列数,支持乱序输入三元组,并计数;
32//以行为主序进行重新排列,并记录每行起始位置于matrix->
rpos[row];
33//若非零元超过MAXSIZE或行数超过MAXRC,则返回ERROR,否则OK;
34
35voidPrintSMatrix_RL(RLSMatrix*matrix);
36//输入矩阵,打印出矩阵的行数、列数、非零元个数,以及整个矩阵;
37
38statusMultSMatrix_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。
46
47/************main()函数对矩阵乘法的实现************/
48
49voidmain()
50{
51RLSMatrix*M,*N,*Q;
52if(!
(M=(RLSMatrix*)malloc(sizeof(RLSMatrix))))
53exit(ERROR);
54if(!
(N=(RLSMatrix*)malloc(sizeof(RLSMatrix))))
55exit(ERROR);
56if(!
(Q=(RLSMatrix*)malloc(sizeof(RLSMatrix))))
57exit(ERROR);
58if(CreateSMatrix_RL(M)&
&
CreateSMatrix_RL(N))
59{
60printf("
/nputoutM:
/n"
);
61PrintSMatrix_RL(M);
/*打印出M*/
62printf("
/nputoutN:
63PrintSMatrix_RL(N);
/*打印出N*/
64if(MultSMatrix_RL(M,N,Q))
65{
66printf("
/n/n/nM*N:
67PrintSMatrix_RL(Q);
/*计算结果*/
68}
69else
70printf("
M.muandN.nuarenotmathing/n"
71}
72else
73printf("
inputerror./n"
74}
75
76
77/***********基本操作的算法描述****************/
78
79statusCreateSMatrix_RL(RLSMatrix*matrix)
80//创建一个稀疏矩阵;
81//输入行数、列数,支持乱序输入三元组,并计数;
82{
83intnum=0,p,q,min,temp;
//中间变量;
84introw;
85printf("
inputthetotalrowandcol:
86scanf("
%d%d"
&
matrix->
mu,&
nu);
//输入行数、列数;
87if(matrix->
mu>
MAXRC)
88returnERROR;
89printf("
rowcolval/n"
90scanf("
%d%d%d"
data[num+1].i,&
data[num+1].j,&
data[num+1].e);
91while(matrix->
data[num+1].i)//乱序输入三元组;
92{
93if(++num>
MAXSIZE)
94returnERROR;
95scanf("
96}
97matrix->
tu=num;
//num的值即为此矩阵的非零元个数;
98for(p=1;
p<
=matrix->
tu-1;
++p)//按行为主序依次重新排列非零元
99{
100min=p;
//使较小的行数、列数的元的序号min为当前值p;
101for(q=p+1;
q<
tu;
++q)//开始依次比较;
102{
103if(matrix->
data[min].i>
data[q].i||(matrix->
data[min].i==matrix->
data[q].i&
data[min].j>
data[q].j))
104min=q;
//在乱序的三元表中,始终保证min是较小的行列数的序号;
105}
106temp=matrix->
data[min].i;
//交换行值;
107matrix->
data[min].i=matrix->
data[p].i;
108matrix->
data[p].i=temp;
109temp=matrix->
data[min].j;
//交换列值;
110matrix->
data[min].j=matrix->
data[p].j;
111matrix->
data[p].j=temp;
112temp=matrix->
data[min].e;
//交换元素值;
113matrix->
data[min].e=matrix->
data[p].e;
114matrix->
data[p].e=temp;
115}
116for(row=1,num=0;
row<
mu;
++row)//记录matrix->
rpos[row];
117{
118matrix->
rpos[row]=num+1;
119while(matrix->
data[num+1].i==row)
120++num;
121}
122returnOK;
123}
124//时间复杂度分析:
125//1.输入非零元:
O(tu);
2.重新排列(最坏情况下);
O(tu*(tu-1));
3.记录行逻辑表:
O(mu)
126voidPrintSMatrix_RL(RLSMatrix*matrix)
127//输入矩阵,打印出矩阵的行数、列数、非零元个数,以及整个矩阵;
128{
129introw,col;
130intnum=0;
131printf("
/nrow:
%dcol:
%dnumber:
%d/n"
matrix->
mu,matrix->
nu,matrix->
tu);
132for(row=1;
++row)
133{
134for(col=1;
col<
nu;
++col)
135{
136if(num+1<
tu&
data[num+1].i==row&
data[num+1].j==col)
137{
138++num;
139printf("
%4d"
data[num].e);
/*当扫描到非零元的行列值与之相等时,输出其值*/
140}
141else
142printf("
NULL);
/*没有非零元的地方补0*/
143}
144printf("
/*每行输入完毕后,换行*/
145}
146}
147
148//时间复杂度:
O(mu*nu).
149
150
151
152statusMultSMatrix_RL(RLSMatrix*M,RLSMatrix*N,RLSMatrix*Q)
153//输入两个稀疏矩阵M和N,并初始化Q,然后计算M*N的值赋给Q
154{
155intarow,brow,ccol;
156int*ctemp;
/*以N的列值为序号的临时数组*/
157inttp,p,tq,q;
/*中间变量*/
158if(M->
nu!
mu)
159returnERROR;
160Q->
mu=M->
/*初始化Q*/
161Q->
nu=N->
162Q->
tu=0;
163if(!
(ctemp=(int*)malloc((N->
nu+1)*sizeof(int))))/*动态建立累加器*/
164exit(ERROR);
165if(M->
tu*N->
tu!
=0)/*Q是非零矩阵*/
166{
167for(arow=1;
arow<
=M->
++arow)/*逐行扫描*/
168{
169for(ccol=1;
ccol<
++ccol)
170ctemp[ccol]=0;
/*初始化累加器*/
171Q->
rpos[arow]=Q->
tu+1;
172if(arow<
M->
173tp=M->
rpos[arow+1];
/*tp是M下一行的序号*/
174else
175tp=M->
176for(p=M->
rpos[arow];
tp;
++p)/*从M的当前行找到元素*/
177{
178brow=M->
/*对应元在N中的行号*/
179if(brow<
N->
180tq=N->
rpos[brow+1];
/*tq是N下一行的行号*/
181else
182tq=N->
183for(q=N->
rpos[brow];
tq;
++q)/*以M的对应元的列号为N的行号进行扫描*/
184{
185ccol=N->
data[q].j;
/*提取对应元的列号*/
186ctemp[ccol]+=M->
data[p].e*N->
data[q].e;
187/*两个对应元的值相乘并累加到以列号为序号的累加器中*/
188}
189}
190for(ccol=1;
=Q->
++ccol)/*将此行非零元压缩入Q中*/
191{
192if(ctemp[ccol])
193{
194if(++Q->
tu>
195returnERROR;
196Q->
data[Q->
tu].i=arow;
197Q->
tu].j=ccol;
198Q->
tu].e=ctemp[ccol];
199}
200}
201}
202}
203returnOK;
204}
205//时间复杂度:
O(M->
mu*(N->
nu+M->
nu*N->
nu+N->
nu));
statusCreateSMatrix_RL(RLSMatrix*matrix)
这个函数用2种算法进行了编写:
第一种不支持乱序输入,而且输入很麻烦。
第二种则使得输入很方便、清楚。
总结一下函数流程:
1.确定功能,详细描述这个功能,即要达到哪些效果。
好的功能能够使程序更加人性化。
2.设计算法。
3.尽量给出此函数的完整定义。