数据结构之稀疏矩阵
Posted Coolxxx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构之稀疏矩阵相关的知识,希望对你有一定的参考价值。
稀疏矩阵
三元组顺序表TSMatrix
三元组顺序表带行表RLSMatrix
基本操作
1 Status CreateSMatrix(TSMatrix &M);//创建稀疏矩阵M 2 Status DestroySMatrix(TSMatrix &M);//销毁稀疏矩阵M 3 Status PrintTSMatrix(TSMatrix M);//输出稀疏矩阵M,三元组形式 4 Status PrintSMatrix(TSMatrix M);//输出稀疏矩阵M,矩阵形式 5 Status TStoRLS(TSMatrix M,RLSMatrix &N);//不带行表转带行表 6 Status RLStoTS(RLSMatrix M,TSMatrix &N);//带行表转不带行表 7 Status CopySMatrix(TSMatrix M,TSMatrix &T);//由稀疏矩阵M复制得到T 8 Status AddSMatrix(TSMatrix M,TSMatrix N,TSMatrix &Q);//求稀疏矩阵的和Q=M+N 9 Status SubtMatrix(TSMatrix M,TSMatrix N,TSMatrix &Q);//求稀疏矩阵的差Q=M-N 10 Status MultSMatrix(TSMatrix M,TSMatrix N,TSMatrix &Q);//求稀疏矩阵乘积Q=MxN 11 Status QuickMultSMatrix(TSMatrix M,TSMatrix N,TSMatrix &Q);//快速求稀疏矩阵乘积Q=MxN,M,N,Q为不带行表 12 Status QuickMultSMatrix(RLSMatrix M,RLSMatrix N,RLSMatrix &Q);//快速求稀疏矩阵乘积Q=MxN,M,N,Q为带行表 13 Status TransposeSMatrix(TSMatrix M,TSMatrix &T);//求稀疏矩阵的转置矩阵T 14 Status FastTransposeSMatrix(TSMatrix M,TSMatrix &T);//快速求稀疏矩阵M的转置矩阵T
程序实现
1 // 2 //by coolxxx 3 //#include<bits/stdc++.h> 4 #include<iostream> 5 #include<algorithm> 6 #include<string> 7 #include<iomanip> 8 #include<map> 9 #include<stack> 10 #include<queue> 11 #include<set> 12 #include<bitset> 13 #include<memory.h> 14 #include<time.h> 15 #include<stdio.h> 16 #include<stdlib.h> 17 #include<string.h> 18 //#include<stdbool.h> 19 #include<math.h> 20 #define min(a,b) ((a)<(b)?(a):(b)) 21 #define max(a,b) ((a)>(b)?(a):(b)) 22 #define abs(a) ((a)>0?(a):(-(a))) 23 #define lowbit(a) (a&(-a)) 24 #define sqr(a) ((a)*(a)) 25 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b)) 26 #define mem(a,b) memset(a,b,sizeof(a)) 27 #define eps (1e-10) 28 #define J 10000 29 #define mod 1000000007 30 #define MAX 0x7f7f7f7f 31 #define PI 3.14159265358979323 32 #pragma comment(linker,"/STACK:1024000000,1024000000") 33 34 const int OK=1; 35 const int ERROR=0; 36 const int INFEASIBLE=-1; 37 typedef int Status; 38 using namespace std; 39 typedef long long LL; 40 double anss; 41 LL aans; 42 int cas,cass; 43 LL n,m,lll,ans; 44 45 typedef int ElemType; 46 const int MAXSIZE=12500;//假设非零元个数的最大值为12500 47 const int MAXRC=1004; 48 typedef struct 49 { 50 int x,y; //该非零元的行下标和列下标 51 ElemType e; 52 }Triple; 53 typedef struct 54 { 55 Triple data[MAXSIZE+1]; //非零元三元组表,data[0]未用 56 int mu,nu,tu; //矩阵的行数、列数和非零元个数 57 }TSMatrix; 58 typedef struct 59 { 60 Triple data[MAXSIZE+1]; //非零元三元组表 61 int rpos[MAXRC+1]; //各行第一个非零元的位置表 62 int mu,nu,tu; //矩阵的行数、列数和非零元个数 63 }RLSMatrix; 64 65 Status CreateSMatrix(TSMatrix &M);//创建稀疏矩阵M 66 Status DestroySMatrix(TSMatrix &M);//销毁稀疏矩阵M 67 Status PrintTSMatrix(TSMatrix M);//输出稀疏矩阵M,三元组形式 68 Status PrintSMatrix(TSMatrix M);//输出稀疏矩阵M,矩阵形式 69 Status TStoRLS(TSMatrix M,RLSMatrix &N);//不带行表转带行表 70 Status RLStoTS(RLSMatrix M,TSMatrix &N);//带行表转不带行表 71 Status CopySMatrix(TSMatrix M,TSMatrix &T);//由稀疏矩阵M复制得到T 72 Status AddSMatrix(TSMatrix M,TSMatrix N,TSMatrix &Q);//求稀疏矩阵的和Q=M+N 73 Status SubtMatrix(TSMatrix M,TSMatrix N,TSMatrix &Q);//求稀疏矩阵的差Q=M-N 74 Status MultSMatrix(TSMatrix M,TSMatrix N,TSMatrix &Q);//求稀疏矩阵乘积Q=MxN 75 Status QuickMultSMatrix(TSMatrix M,TSMatrix N,TSMatrix &Q);//快速求稀疏矩阵乘积Q=MxN,M,N,Q为不带行表 76 Status QuickMultSMatrix(RLSMatrix M,RLSMatrix N,RLSMatrix &Q);//快速求稀疏矩阵乘积Q=MxN,M,N,Q为带行表 77 Status TransposeSMatrix(TSMatrix M,TSMatrix &T);//求稀疏矩阵的转置矩阵T 78 Status FastTransposeSMatrix(TSMatrix M,TSMatrix &T);//快速求稀疏矩阵M的转置矩阵T 79 80 Status CreateSMatrix(TSMatrix &M)//创建稀疏矩阵M 81 { 82 int i,j,k,x,y; 83 ElemType e; 84 puts("请输入矩阵的行数,列数,非零元个数:"); 85 scanf("%d %d %d",&M.mu,&M.nu,&M.tu); 86 M.data[0].x=0;//为以下比较顺序做准备 87 for(i=1;i<=M.tu;i++) 88 { 89 loop:printf("请按行序顺序输入第%d个非零元素所在的行(1~%d) 列(1~%d) 元素值:\n",i,M.mu,M.nu); 90 scanf("%d%d%d",&x,&y,&e); 91 k=0; 92 if(x<1 || x>M.mu || y<1 || y>M.nu)//行或列超出范围 93 k=1; 94 if(x<M.data[i-1].x || (x==M.data[i-1].x && y<=M.data[i-1].y))//行或列的顺序有错 95 k=1; 96 if(k)goto loop; 97 M.data[i].x=x,M.data[i].y=y,M.data[i].e=e; 98 } 99 return OK; 100 }//CreateSMatrix 101 102 Status DestroySMatrix(TSMatrix &M)//销毁稀疏矩阵M 103 { 104 M.mu=M.nu=M.tu=0; 105 }//DestroySMatrix 106 107 Status PrintTSMatrix(TSMatrix M)//输出稀疏矩阵M,三元组形式 108 { 109 int i; 110 printf("%d行%d列%d个非零元素。\n",M.mu,M.nu,M.tu); 111 for(i=1;i<=M.tu;i++) 112 printf("%3d%3d%6d\n",M.data[i].x,M.data[i].y,M.data[i].e); 113 }//PrintSMatrix 114 115 Status PrintSMatrix(TSMatrix M)//输出稀疏矩阵M,矩阵形式 116 { 117 int i,j; 118 printf("%d行%d列%d个非零元素。\n",M.mu,M.nu,M.tu); 119 ElemType *temp=(ElemType *)malloc(M.mu*M.nu*sizeof(ElemType)); 120 for(i=0;i<M.mu*M.nu;i++)temp[i]=0; 121 for(i=1;i<=M.tu;i++) 122 temp[(M.data[i].x-1)*M.nu+M.data[i].y-1]=M.data[i].e; 123 for(i=1;i<=M.mu;i++,puts("")) 124 for(j=1;j<=M.nu;j++) 125 printf("%d ",temp[(i-1)*M.nu+j-1]); 126 return OK; 127 }//PrintSMatrix 128 129 Status TStoRLS(TSMatrix M,RLSMatrix &N)//不带行表转带行表 130 { 131 int i,j; 132 N.mu=M.mu,N.nu=M.nu,N.tu=M.tu; 133 for(i=1;i<=N.tu;i++)N.data[i]=M.data[i]; 134 N.rpos[M.data[1].x]=1; 135 for(i=1;i<M.data[1].x;i++)N.rpos[i]=1; 136 for(i=2;i<=M.tu;i++) 137 if(M.data[i].x!=M.data[i-1].x) 138 { 139 for(j=M.data[i-1].x+1;j<M.data[i].x;j++)N.rpos[j]=N.rpos[M.data[i-1].x]; 140 N.rpos[M.data[i].x]=i; 141 } 142 for(i=M.data[M.tu].x+1;i<=M.mu;i++)N.rpos[i]=N.tu+1; 143 return OK; 144 }//TStoRLS 145 146 Status RLStoTS(RLSMatrix M,TSMatrix &N)//带行表转不带行表 147 { 148 int i; 149 N.mu=M.mu,N.nu=M.nu,N.tu=M.tu; 150 for(i=1;i<=N.tu;i++)N.data[i]=M.data[i]; 151 return OK; 152 }//RLStoTS 153 154 Status CopySMatrix(TSMatrix M,TSMatrix &T)//由稀疏矩阵M复制得到T 155 { 156 T=M; 157 }//CopySMatrix 158 159 Status AddSMatrix(TSMatrix M,TSMatrix N,TSMatrix &Q)//求稀疏矩阵的和Q=M+N 160 { 161 int i,j,&k=Q.tu; 162 Q.mu=M.mu,Q.nu=M.nu,k=0; 163 for(i=1,j=1;i<=M.tu && j<=N.tu;) 164 { 165 if(M.data[i].x==N.data[j].x && M.data[i].y==N.data[j].y) 166 { 167 Q.data[++k]=M.data[i++]; 168 Q.data[k].e+=N.data[j++].e; 169 if(!Q.data[k].e)k--; 170 } 171 else if(M.data[i].x==N.data[j].x) 172 { 173 if(M.data[i].y<N.data[j].y) 174 Q.data[++k]=M.data[i++]; 175 else Q.data[++k]=N.data[j++]; 176 if(!Q.data[k].e)k--; 177 } 178 else 179 { 180 if(M.data[i].x<N.data[j].x) 181 Q.data[++k]=M.data[i++]; 182 else Q.data[++k]=N.data[j++]; 183 if(!Q.data[k].e)k--; 184 } 185 } 186 for(;i<=M.tu;i++)Q.data[++k]=M.data[i]; 187 for(;j<=N.tu;j++)Q.data[++k]=N.data[j]; 188 return OK; 189 }//AddSMatrix 190 191 Status SubtMatrix(TSMatrix M,TSMatrix N,TSMatrix &Q)//求稀疏矩阵的差Q=M-N 192 { 193 int i; 194 for(i=1;i<=N.tu;i++)N.data[i].e*=-1; 195 AddSMatrix(M,N,Q); 196 return OK; 197 }//SubtMatrix 198 199 Status MultSMatrix(TSMatrix M,TSMatrix N,TSMatrix &Q)//求稀疏矩阵乘积Q=MxN 200 { 201 int i,j; 202 ElemType *q; 203 if(M.nu!=N.mu)return ERROR; 204 Q.mu=M.mu,Q.nu=N.nu;Q.tu=0; 205 q=(ElemType *)malloc(Q.mu*Q.nu*sizeof(ElemType)); 206 for(i=0;i<Q.mu*Q.nu;i++)q[i]=0; 207 for(i=1;i<=M.tu;i++) 208 for(j=1;j<=N.tu;j++) 209 if(M.data[i].y==N.data[j].x) 210 q[(M.data[i].x-1)*Q.nu+N.data[j].y-1]+=M.data[i].e*N.data[j].e; 211 for(i=1;i<=Q.mu;i++) 212 for(j=1;j<=Q.nu;j++) 213 if(q[(i-1)*Q.nu+j-1]) 214 { 215 ++Q.tu; 216 Q.data[Q.tu].x=i; 217 Q.data[Q.tu].y=j; 218 Q.data[Q.tu].e=q[(i-1)*Q.nu+j-1]; 219 } 220 free(q); 221 return OK; 222 }//MultSMatrix 223 224 Status QuickMultSMatrix(RLSMatrix M,RLSMatrix N,RLSMatrix &Q)//快速求稀疏矩阵乘积Q=MxN,M,N,Q为带行表 225 { 226 int arow,brow,crow,col,p,q,tp,t; 227 ElemType temp[MAXRC]; 228 if(M.nu!=N.mu)return ERROR; 229 Q.mu=M.mu,Q.nu=N.nu;Q.tu=0;//初始化 230 if(Q.mu*Q.nu)//Q是非零矩阵 231 { 232 for(arow=1;arow<=M.mu;arow++)//处理M的每一行 233 { 234 mem(temp,0);//当前行各元素累加器清零 235 Q.rpos[arow]=Q.tu+1; 236 if(arow<M.mu)tp=M.rpos[arow+1]; 237 else tp=M.tu+1; 238 for(p=M.rpos[arow];p<tp;p++)//怼当前行中每一个非零元 239 { 240 brow=M.data[p].y;//找到对应元在N中的序号 241 if(brow<N.mu)t=N.rpos[brow+1]; 242 else t=N.tu+1; 243 for(q=N.rpos[brow];q<t;q++) 244 { 245 col=N.data[q].y; 246 temp[col]+=M.data[p].e*N.data[q].e; 247 } 248 }//求得Q中第crow(=arow)行的非零元 249 for(col=1;col<=Q.nu;col++)//压缩存储该行非零元 250 if(temp[col]) 251 { 252 if(++Q.tu>MAXSIZE)return ERROR; 253 Q.data[Q.tu].x=arow,Q.data[Q.tu].y=col,Q.data[Q.tu].e=temp[col]; 254 } 255 } 256 } 257 return OK; 258 }//QuickMultSMatrix 259 260 Status QuickMultSMatrix(TSMatrix M,TSMatrix N,TSMatrix &Q)//快速求稀疏矩阵乘积Q=MxN,M,N,Q为不带行表 261 { 262 RLSMatrix M1,N1,Q1; 263 TStoRLS(M,M1); 264 TStoRLS(N,N1); 265 QuickMultSMatrix(M1,N1,Q1); 266 RLStoTS(Q1,Q); 267 }//QucikMultSMatrix 268 269 Status TransposeSMatrix(TSMatrix M,TSMatrix &T)//求稀疏矩阵的转置矩阵T 270 { 271 int col,p,q; 272 T.mu=M.nu,T.nu=M.mu,T.tu=M.tu; 273 if(T.tu) 274 { 275 q=1; 276 for(col=1;col<=M.nu;col++) 277 for(p=1;p<=M.tu;p++) 278 if(M.data[p].y==col) 279 { 280 T.data[q].x=M.data[p].y;T.data[q].y=M.data[p].x; 281 T.data[q].e=M.data[p].e;q++; 282 } 283 } 284 return OK; 285 }//TransposeSMatrix 286 287 Status FastTransposeSMatrix(TSMatrix M,TSMatrix &T)//快速求稀疏矩阵M的转置矩阵T 288 { 289 int i,col,p,q,num[MAXRC]={0},cpot[MAXRC]; 290 T.mu=M.nu,T.nu=M.mu,T.tu=M.tu; 291 if(T.tu) 292 { 293 for(i=1;i<=M.tu;i++)num[M.data[i].y]++;//求M中每一列含非零元个数 294 //求第col列中第一个非零元在b.data中的序号 295 for(cpot[1]=1,col=2;col<=M.nu;col++)cpot[col]=cpot[col-1]+num[col-1]; 296 for(p=1;p<=M.tu;p++) 297 { 298 col=M.data[p].y;q=cpot[col]; 299 T.data[q].x=M.data[p].y;T.data[q].y=M.data[p].x; 300 T.data[q].e=M.data[p].e;cpot[col]++; 301 } 302 } 303 return OK; 304 }//FastTransposeSMatrix 305 306 void CheckTSMatrix() 307 { 308 TSMatrix M,N,Q,T; 309 CreateSMatrix(M); 310 CreateSMatrix(N); 311 puts("转置M"); 312 TransposeSMatrix(M,Q); 313 PrintSMatrix(Q); 314 puts("快速转置M"); 315 FastTransposeSMatrix(M,T); 316 PrintSMatrix(T); 317 puts("复制M"); 318 CopySMatrix(M,Q); 319 PrintSMatrix(Q); 320 puts("M+Q"); 321 AddSMatrix(M,Q,T); 322 PrintSMatrix(T); 323 puts("M-Q"); 324 SubtMatrix(M,Q,T); 325 PrintSMatrix(T); 326 puts("MxN"); 327 MultSMatrix(M,N,Q); 328 PrintSMatrix(Q); 329 QuickMultSMatrix(M,N,T); 330 PrintSMatrix(T); 331 puts("销毁"); 332 DestroySMatrix(Q); 333 DestroySMatrix(T); 334 PrintSMatrix(Q); 335 DestroySMatrix(M); 336 DestroySMatrix(N); 337 } 338 int main() 339 { 340 #ifndef ONLINE_JUDGEW 341 // freopen("1.txt","r",stdin); 342 // freopen("2.txt","w",stdout); 343 #endif 344 int i,j,k; 345 int x,y,z,xx,yy; 346 // init(); 347 // for(scanf("%d",&cass);cass;cass--) 348 // for(scanf("%d",&cas),cass=1;cass<=cas;cass++) 349 // while(~scanf("%s",s)) 350 // while(~scanf("%d%d",&n,&m)) 351 { 352 CheckTSMatrix(); 353 } 354 return 0; 355 } 356 /* 357 // 358 359 // 360 */
以上是关于数据结构之稀疏矩阵的主要内容,如果未能解决你的问题,请参考以下文章