稀疏矩陣的c實現
阿新 • • 發佈:2018-11-30
//稀疏矩陣三元組順序表儲存表示 #include <stdio.h> #include <stdlib.h> #define MAXSIZE 100 typedef int ElemType; typedef struct { int i,j; // 行下標,列下標 ElemType e; // 非零元素值 }Triple; typedef struct { Triple data[MAXSIZE+1]; // 非零元三元組表,data[0]未用 int mu,nu,tu; // 矩陣的行數、列數和非零元個數 }TSMatrix; // 建立稀疏矩陣M int CreateSMatrix(TSMatrix *M) { int i,m,n; ElemType e; int k; printf("請輸入矩陣的行數, 列數, 非零元素個數:(以逗號隔開)\n"); scanf("%d,%d,%d", &(*M).mu, &(*M).nu, &(*M).tu); (*M).data[0].i=0; for(i = 1; i <= (*M).tu; i++) { do { printf("請按行序輸入第 %d 個非零元素的行( 1 ~ %d )," "列 ( 1 ~ %d ),元素值:(以逗號隔開)\n", i , (*M).mu, (*M).nu); scanf("%d,%d,%d", &m, &n, &e); k=0; if(m < 1 || m > (*M).mu || n < 1 || n > (*M).nu) k=1; if(m < (*M).data[i-1].i || m == (*M).data[i-1].i && n <= (*M).data[i-1].j) k=1; }while(k); (*M).data[i].i = m; //行下標 (*M).data[i].j = n; //列下標 (*M).data[i].e = e; //該下標所對應的值 } return 1; } // 銷燬稀疏矩陣M,所有元素置空 void DestroySMatrix(TSMatrix *M) { (*M).mu=0; (*M).nu=0; (*M).tu=0; } // 輸出稀疏矩陣M void PrintSMatrix(TSMatrix M) { int i; printf("\n %d 行, %d 列, %d 個非零元素。\n",M.mu, M.nu, M.tu); printf("======================\n"); printf("%4s %4s %8s\n", "i", "j", "e"); printf("======================\n"); for(i=1;i<=M.tu;i++) printf("%4d %4d %8d\n", M.data[i].i, M.data[i].j, M.data[i].e); printf("======================\n"); } // 由稀疏矩陣M複製得到T int CopySMatrix(TSMatrix M,TSMatrix *T) { (*T)=M; return 1; } // AddSMatrix函式要用到 int comp(int c1,int c2) { int i; if(c1<c2) i=1; else if(c1==c2) i=0; else i=-1; return i; } // 求兩個稀疏矩陣的和Q=M+N int AddSMatrix(TSMatrix M,TSMatrix N,TSMatrix *Q) { Triple *Mp,*Me,*Np,*Ne,*Qh,*Qe; if(M.mu!=N.mu) return 0; if(M.nu!=N.nu) return 0; (*Q).mu=M.mu; (*Q).nu=M.nu; Mp=&M.data[1]; // Mp的初值指向矩陣M的非零元素首地址 Np=&N.data[1]; // Np的初值指向矩陣N的非零元素首地址 Me=&M.data[M.tu]; // Me指向矩陣M的非零元素尾地址 Ne=&N.data[N.tu]; // Ne指向矩陣N的非零元素尾地址 Qh=Qe=(*Q).data; // Qh、Qe的初值指向矩陣Q的非零元素首地址的前一地址 while(Mp <= Me && Np <= Ne) { Qe++; switch(comp(Mp->i,Np->i)) { case 1: *Qe=*Mp; Mp++; break; case 0: // M、N矩陣當前非零元素的行相等,繼續比較列 switch(comp(Mp->j,Np->j)) { case 1: *Qe=*Mp; Mp++; break; case 0: *Qe=*Mp; Qe->e+=Np->e; if(!Qe->e) // 元素值為0,不存入壓縮矩陣 Qe--; Mp++; Np++; break; case -1: *Qe=*Np; Np++; } break; case -1: *Qe=*Np; Np++; } } if(Mp>Me) // 矩陣M的元素全部處理完畢 while(Np<=Ne) { Qe++; *Qe=*Np; Np++; } if(Np>Ne) // 矩陣N的元素全部處理完畢 while(Mp<=Me) { Qe++; *Qe=*Mp; Mp++; } (*Q).tu=Qe-Qh; // 矩陣Q的非零元素個數 return 1; } //求兩個稀疏矩陣的差Q=M-N int SubtSMatrix(TSMatrix M,TSMatrix N,TSMatrix *Q) { int i; for(i=1;i<=N.tu;i++) N.data[i].e*=-1; AddSMatrix(M,N,Q); return 1; } //求兩個稀疏矩陣的乘積Q = M*N int MultSMatrix(TSMatrix M,TSMatrix N,TSMatrix *Q) { // h,l分別為矩陣Q的行、列值,Qn為矩陣Q的非零元素個數,初值為0 int i,j,h=M.mu,l=N.nu,Qn=0; ElemType *Qe; if(M.nu!=N.mu) return 0; (*Q).mu=M.mu; (*Q).nu=N.nu; Qe=(ElemType *)malloc(h*l*sizeof(ElemType)); // Qe為矩陣Q的臨時陣列 // 矩陣Q的第i行j列的元素值存於*(Qe+(i-1)*l+j-1)中,初值為0 for(i=0;i<h*l;i++) *(Qe+i)=0; // 賦初值0 for(i=1;i<=M.tu;i++) // 矩陣元素相乘,結果累加到Qe for(j=1;j<=N.tu;j++) if(M.data[i].j==N.data[j].i) *(Qe+(M.data[i].i-1)*l+N.data[j].j-1) += M.data[i].e * N.data[j].e; for(i=1;i<=M.mu;i++) for(j=1;j<=N.nu;j++) if(*(Qe+(i-1)*l+j-1)!=0) { Qn++; (*Q).data[Qn].e=*(Qe+(i-1)*l+j-1); (*Q).data[Qn].i=i; (*Q).data[Qn].j=j; } free(Qe); (*Q).tu=Qn; return 1; } //稀疏矩陣的轉置 int transposeSMatrix(TSMatrix M,TSMatrix *T) { int p,q,col; (*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 1; } // 快速求稀疏矩陣M的轉置矩陣 int FasttransposeSMatrix(TSMatrix M,TSMatrix *T) { int p,q,t,col,*num,*cpot; num=(int *)malloc((M.nu+1)*sizeof(int)); // 生成陣列([0]不用) cpot=(int *)malloc((M.nu+1)*sizeof(int)); // 生成陣列([0]不用) (*T).mu=M.nu; (*T).nu=M.mu; (*T).tu=M.tu; if((*T).tu) { for(col=1;col<=M.nu;++col) num[col]=0; // 設初值 for(t=1;t<=M.tu;++t) // 求M中每一列含非零元素個數 ++num[M.data[t].j]; cpot[1]=1; // 求第col列中第一個非零元在(*T).data中的序號 for(col=2;col<=M.nu;++col) cpot[col]=cpot[col-1]+num[col-1]; for(p=1;p<=M.tu;++p) { col=M.data[p].j; q=cpot[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; ++cpot[col]; } } free(num); free(cpot); return 1; } int main() { TSMatrix A,B,C; CreateSMatrix(&A); printf("矩陣A:\n"); PrintSMatrix(A); printf("\n\n"); CopySMatrix(A,&B); printf("矩陣B:\n"); PrintSMatrix(B); printf("\n\n"); printf("矩陣C1為:(A+B): \n"); AddSMatrix(A,B,&C); PrintSMatrix(C); DestroySMatrix(&C); printf("\n\n"); printf("矩陣C2為 :(A-B): \n"); SubtSMatrix(A,B,&C); PrintSMatrix(C); DestroySMatrix(&C); printf("\n\n"); printf("矩陣C3為 :(A的轉置): \n"); transposeSMatrix(A,&C); PrintSMatrix(C); return 0; }