zoukankan      html  css  js  c++  java
  • 数据结构之稀疏矩阵

    稀疏矩阵

    三元组顺序表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) 元素值:
    ",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个非零元素。
    ",M.mu,M.nu,M.tu);
    111     for(i=1;i<=M.tu;i++)
    112         printf("%3d%3d%6d
    ",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个非零元素。
    ",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 */
  • 相关阅读:
    验证回文串
    03-Python控制语句
    02-Python运算符
    ACwing(基础) --- Bellman-Ford&SPFA
    ACwing(基础)--- Dijkstra算法(含堆优化版)
    ACwing(基础)--- 区间合并
    ACwing(基础)--- 位运算
    ACwing(基础)--- 双指针算法
    ACwing(基础)--- 高精度
    ACwing(基础)---790. 数的三次方根
  • 原文地址:https://www.cnblogs.com/Coolxxx/p/5975261.html
Copyright © 2011-2022 走看看