稀疏矩阵乘法器

稀疏矩阵

1、定义稀疏矩阵的数据结构,是个三元组

#include<stdio.h>
#define MAXSIZE 12500
typedef struct{
    int i,j;
    int e;
}Triple;
typedef struct{
    Triple data[MAXSIZE+1];
    int mu,nu,tu;  //mu行数,nu列数,tu非零元个数
}TSMatrix;

2、基本操作:创建、销毁、打印稀疏矩阵

void CreateSMatrix_T(TSMatrix *M){
    printf("输入行数:");
    scanf("%d",&M->mu);
    printf("输入列数:");
    scanf("%d",&M->nu);
    printf("输入非零元个数:");
    scanf("%d",&M->tu);
    for(int k=1;k<=M->tu;k++){
        scanf("%d %d %d",&M->data[k].i,&M->data[k].j,&M->data[k].e);
    }
}
void DestroySMatrix_T(TSMatrix *M){
    M->nu=0;
    M->nu=0;
    M->tu=0;
}
void PrintSMatrix_T(TSMatrix M) {
    if (M.tu) {
        int r, c,dataflag=1;
        for (r=1;r<= M.mu; r++) {
            for (c = 1; c <= M.nu; c++) {
                if (M.data[dataflag].j == c&&M.data[dataflag].i==r) {
                    printf("%3d", M.data[dataflag].e);
                    dataflag++;
                }
                else printf("%3d", 0);
            }
            printf("\n");
        }
    }
}
void CopySMatrix_T(TSMatrix M, TSMatrix *T){
    (*T)=M;
}

3、加法器、减法器


```go

```c
//稀疏矩阵加法器
void AddSMatri_T(TSMatrix M, TSMatrix N, TSMatrix *Q){
    if(M.mu==N.mu&&M.nu==N.nu){
        Q->nu=M.nu;
        Q->mu=M.mu;
        Q->tu=0;
        int r=1,c=1,m=1;
        while(r<=M.tu&&c<=N.tu){
            //先比较行数,行数优先
            if(M.data[r].i<N.data[c].i){
                Q->data[m++]=M.data[r++];
            }
            else if(M.data[r].i>N.data[c].i){
                Q->data[m++]=N.data[c++];
            }
            //行数相等比较列数
            else{
                if(M.data[r].j<N.data[c].j){
                    Q->data[m++]=M.data[r++];
                }
                else if(M.data[r].j>N.data[c].j){
                    Q->data[m++]=N.data[c++];
                }//如果行数和列数相等,则考虑数值相加是否为0
                else{
                    if(M.data[r].e+N.data[c].e==0){
                        r++;c++;continue;
                    }else{
                        Q->data[m].i=M.data[r].i;
                        Q->data[m].j=M.data[r].j;
                        Q->data[m++].e=M.data[r++].e+N.data[c++].e;
                    }
                }
            }
            Q->tu++;
        }
        while(r<=M.tu){
            Q->data[m++]=M.data[r++];
        }
        while(c<=N.tu){
            Q->data[m++]=N.data[c++];
        }
    }else{
        printf("两矩阵不能相加");
    }
}

//稀疏矩阵减法器
void SubSMatrix_T(TSMatrix M, TSMatrix N, TSMatrix *Q){  //M-N
    if(M.mu==N.mu&&M.nu==N.nu){
        Q->nu=M.nu;
        Q->mu=M.mu;
        int r=1,c=1,m=1;
        while(r<=M.tu&&c<=N.tu){
            //先比较行数,行数优先
            if(M.data[r].i<N.data[c].i){
                Q->data[m++]=M.data[r++];
            }
            else if(M.data[r].i>N.data[c].i){
                Q->data[m].i=N.data[c].i;
                Q->data[m].j=N.data[c].j;
                Q->data[m++].e=-N.data[c++].e;
            }
            //行数相等比较列数
            else{
                if(M.data[r].j<N.data[c].j){
                    Q->data[m++]=M.data[r++];
                }
                else if(M.data[r].j>N.data[c].j){
                    Q->data[m].i=N.data[c].i;
                    Q->data[m].j=N.data[c].j;
                    Q->data[m++].e=-N.data[c++].e;
                }//如果行数和列数相等,则考虑数值相加是否为0
                else{
                    if(M.data[r].e-N.data[c].e==0){
                        r++;c++;continue;
                    }else{
                        Q->data[m].i=M.data[r].i;
                        Q->data[m].j=M.data[r].j;
                        Q->data[m++].e=M.data[r++].e-N.data[c++].e;
                    }
                }
            }
            Q->tu++;
        }
        while(r<=M.tu){
            Q->data[m++]=M.data[r++];
        }
        while(c<=N.tu){
            Q->data[m].i=N.data[c].i;
            Q->data[m].j=N.data[c].j;
            Q->data[m++].e=-N.data[c++].e;
        }
    }else{
        printf("两矩阵不能相减");
    }
}

4、乘法器

//稀疏矩阵乘法器
int MultSMatrix_T(TSMatrix M, TSMatrix N, TSMatrix *Q){
    int m,n,i,j,k;
    int c,c1,c2;                            //c存放Q当前行列的值
    if(M.nu!=N.mu)							//M列数等于N行数
    {
        printf("两矩阵不能相乘!!\n");
        return 0;
    }
    Q->mu = M.mu;							//Q初始化
    Q->nu = N.nu;
    Q->tu = 0;
    if(M.tu*N.tu)							//Q是非零矩阵
    {
        for(i=1; i<=M.mu; i++)				//传统矩阵乘法
        {
            for(j=1; j<=N.nu; j++)
            {
                c = 0;
                for(k=1; k<=M.nu; k++)   //k<=  (M.nu==N.mu)
                {
                    c1 = 0;
                    for(m=1; m<=M.tu; m++)	//依次寻找位于指定位置的M三元组
                    {
                        if(M.data[m].i==i && M.data[m].j==k)
                        {
                            c1 = M.data[m].e;
                            break;
                        }
                    }
                    c2 = 0;
                    for(n=1; n<=N.tu; n++)	//依次寻找位于指定位置的N三元组
                    {
                        if(N.data[n].i==k && N.data[n].j==j)
                        {
                            c2 = N.data[n].e;
                            break;
                        }
                    }
                    if(c1 && c2)
                        c += c1 * c2;    //计算M(i,k)*N(k,j)的和
                }
                if(c)
                {
                    Q->tu++;
                    Q->data[Q->tu].i = i;
                    Q->data[Q->tu].j = j;
                    Q->data[Q->tu].e = c;
                }
            }
        }
    }

    return 1;
}

5、转置算法,包含一般转置和快速转置

//5.1矩阵转置
void TransposeSMatrix_T(TSMatrix M, TSMatrix *T){
    T->mu=M.nu;T->nu=M.mu;T->tu=M.tu;
    if(T->tu){
        int q=1;
        for(int col=1;col<=M.nu;col++)  //先遍历列数,如果在M中存在,则放到T的行数中去
            for(int 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++;
                }
    }
}

//5.2快速转置
void FastTransposeSMatrix_T(TSMatrix M, TSMatrix *T){
    T->mu=M.nu;T->nu=M.mu;T->tu=M.tu;
    int col,p,q;
    int num[M.nu+1];
    int cpot[M.nu+1];
    if(T->tu){
        for(col=1;col<=M.nu;col++) num[col]=0;
        //求M中每一列含非零元的个数
        for(int k=0;k<=M.tu;k++){
            num[M.data[k].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]++;  //该个元素存完后,往后+1
        }
    }
}

6、测试函数

//测试函数
int main()
{
    TSMatrix M, N;
    int testsequence;
    printf("请输入调试项目");
    printf("1:函数CreateSMatrix_T测试\n");
    printf("2:函数CopySMatrix_T测试\n");
    printf("3:函数AddSMatri_T测试\n");
    printf("4:函数SubSMatrix_T测试\n");
    printf("5:函数MultSMatrix_T测试\n");
    printf("6:函数TransposeSMatrix_T测试\n");
    printf("7:函数FastTransposeSMatrix_T测试\n");
    printf("0:退出调试\n");
    scanf("%d",&testsequence);
    while(testsequence) {
        switch (testsequence) {
            case 1: {
                CreateSMatrix_T(&M);
                PrintSMatrix_T(M);
                printf("请输入调试项目");
                scanf("%d", &testsequence);
                break;
            }
            case 2: {
                CreateSMatrix_T(&M);
                PrintSMatrix_T(M);
                CopySMatrix_T(M, &N);
                printf("copy后的矩阵");
                PrintSMatrix_T(N);
                printf("请输入调试项目");
                scanf("%d", &testsequence);
                break;
            }
            case 3: {
                TSMatrix Q;
                CreateSMatrix_T(&M);
                PrintSMatrix_T(M);
                CreateSMatrix_T(&N);
                PrintSMatrix_T(N);
                AddSMatri_T(M, N, &Q);
                printf("加法后的矩阵\n");
                PrintSMatrix_T(Q);
                printf("请输入调试项目");
                scanf("%d", &testsequence);
                break;
            }
            case 4: {
                TSMatrix Q;
                CreateSMatrix_T(&M);
                PrintSMatrix_T(M);
                CreateSMatrix_T(&N);
                PrintSMatrix_T(N);
                SubSMatrix_T(M, N, &Q);
                printf("减法后的矩阵\n");
                PrintSMatrix_T(Q);
                printf("请输入调试项目");
                scanf("%d", &testsequence);
                break;
            }
            case 5: {
                TSMatrix Q;
                CreateSMatrix_T(&M);
                PrintSMatrix_T(M);
                CreateSMatrix_T(&N);
                PrintSMatrix_T(N);
                MultSMatrix_T(M, N, &Q);
                printf("乘法后的矩阵:\n");
                PrintSMatrix_T(Q);
                printf("请输入调试项目");
                scanf("%d", &testsequence);
                break;
            }
            case 6: {
                TSMatrix T;
                CreateSMatrix_T(&M);
                PrintSMatrix_T(M);
                TransposeSMatrix_T(M, &T);
                printf("转置后的矩阵:\n");
                PrintSMatrix_T(T);
                printf("请输入调试项目");
                scanf("%d", &testsequence);
                break;
            }
            case 7: {
                TSMatrix T;
                CreateSMatrix_T(&M);
                PrintSMatrix_T(M);
                FastTransposeSMatrix_T(M, &T);
                printf("快速转置后的矩阵:\n");
                PrintSMatrix_T(T);
                printf("请输入调试项目");
                scanf("%d", &testsequence);
                break;
            }
            default: {
                printf("请重新输入");
                scanf("%d", &testsequence);
                break;
            }
        }
    }
    return 0;
}
发布了26 篇原创文章 · 获赞 39 · 访问量 1826

猜你喜欢

转载自blog.csdn.net/matafeiyanll/article/details/102740939
今日推荐