欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

第五章 数组和广义表(4)三元组矩阵转换(转)

程序员文章站 2024-01-16 10:56:10
...
#include <stdio.h>  
  
#define OK 1  
#define ERROR 0  
#define TRUE 1  
#define FALSE 0  
  
#define MAXSIZE 100  
  
typedef int Status;  
typedef float ElemType;  
typedef struct{//三元组结构  
    int i,j;//非零元素行下标和列下标  
    ElemType e;//非零元素值  
}Triple;  
typedef struct{  
    Triple data[MAXSIZE+1];//非零元三元组表,data[0]不用  
    int mu,nu,tu;//矩阵的行数、列数和非零元素个数  
}TSMatrix;  
  
TSMatrix NewMatrix(int m,int n);  
    //新建一个三元组表示的稀疏矩阵  
Status InsertElem(TSMatrix *M,int row,int col,ElemType e);  
    //在三元组表示的稀疏矩阵M,第 row 行,第 col 列位置插入元素e  
    //插入成功,返回OK,否则返回ERROR  
Status FindElem(const TSMatrix *M,int row,int col,ElemType *e);  
    //查找三元组表示的稀疏矩阵M中,第 row 行,第 col列元素,若不为0,  
    //则用e返回其值,并返回TRUE,否则返回FALSE  
Status TransposeSMatrix(const TSMatrix *M,TSMatrix *T);  
    //采用三元组表存储表示,求稀疏矩阵M的转置矩阵T  
Status FastTransposeSMatrix(const TSMatrix *M,TSMatrix *T);  
    //利用三元组顺序表存储表示,求稀疏矩阵M的转置矩阵T  
Status MultSMatrix(const TSMatrix *M,const TSMatrix *T,TSMatrix *Q);  
    //稀疏矩阵的乘法,如果符合乘法规则,Q返回M*T结果,并返回OK,否则返回ERROR  
void PrintSMatrix(const TSMatrix *M);  
    //打印稀疏矩阵所有元素  
  
int main()  
{  
    TSMatrix M=NewMatrix(3,4);  
    TSMatrix T;  
    TSMatrix Q;  
    InsertElem(&M,3,2,3.65);  
    InsertElem(&M,2,2,2.31);  
    printf("\nM:");  
    PrintSMatrix(&M);  
    FastTransposeSMatrix(&M,&T);  
    printf("\nT(Transpose of M):");  
    PrintSMatrix(&T);  
    MultSMatrix(&M,&T,&Q);  
    printf("\nM*T=");  
    PrintSMatrix(&Q);  
    return 0;  
}  
  
TSMatrix NewMatrix(int m,int n){  
    //新建一个三元组表示的稀疏矩阵  
    TSMatrix M;  
    M.mu=m;  
    M.nu=n;  
    M.tu=0;  
    return M;  
}  
  
Status InsertElem(TSMatrix *M,int row,int col,ElemType e){  
    //在三元组表示的稀疏矩阵M,第 row 行,第 col 列位置插入元素e  
    //插入成功,返回OK,否则返回ERROR  
    int i,t,p;  
    if(M->tu>=MAXSIZE){//当前三元组表已满  
        printf("\nError:There is no space in the matrix;\n");  
        return ERROR;  
    }  
    if(row>M->mu||col>M->nu||row<1||col<1){//插入位置越界,不在1~mu或1~nu之间  
        printf("\nError:Insert position is beyond the arrange.\n");  
        return ERROR;  
    }  
    p=1;//标志新元素应该插入的位置  
    if(M->tu==0){//插入前矩阵M没有非零元素  
        M->data[p].i=row;  
        M->data[p].j=col;  
        M->data[p].e=e;  
        M->tu++;  
        return OK;  
    }  
    for(t=1;t<=M->tu;t++)//寻找合适的插入位置  
        if((row>=M->data[t].i)&&(col>=M->data[t].j))  
                p++;  
    if(row==M->data[t-1].i && col==M->data[t-1].j){//插入前,该元素已经存在  
        M->data[t-1].e=e;  
        return OK;  
    }  
    for(i=M->tu;i>=p;i--){//移动p之后的元素  
        M->data[i+1].i=M->data[i].i;  
        M->data[i+1].j=M->data[i].j;  
        M->data[i+1].e=M->data[i].e;  
    }  
    //插入新元素  
    M->data[p].i=row;  
    M->data[p].j=col;  
    M->data[p].e=e;  
    M->tu++;  
    return OK;  
}  
  
Status FindElem(const TSMatrix *M,int row,int col,ElemType *e){  
    //查找三元组表示的稀疏矩阵M中,第 row 行,第 col列元素,若不为0,  
    //则用e返回其值,并返回TRUE,否则返回FALSE  
    int p;  
    for(p=1;p<=M->tu;p++)  
        if(M->data[p].i==row&&M->data[p].j==col){  
            *e=M->data[p].e;  
            return TRUE;  
        }  
    return FALSE;  
}  
  
Status TransposeSMatrix(const TSMatrix *M,TSMatrix *T){  
    //采用三元组表存储表示,求稀疏矩阵M的转置矩阵T  
    int col,p,q;  
    T->mu=M->nu;    T->nu=M->mu; T->tu=M->tu;  
    if(T->tu){  
        q=1;  
        for(col=1;col<=M->mu;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 OK;  
}  
  
Status FastTransposeSMatrix(const TSMatrix *M,TSMatrix *T){  
    //利用三元组顺序表存储表示,求稀疏矩阵M的转置矩阵T  
    int col,t,p,q,*num,*cpot;  
    T->mu=M->nu;    T->nu=M->mu;    T->tu=M->tu;  
    if(T->tu){  
        num=(int *)malloc(sizeof(int)*M->tu);  
        cpot=(int *)malloc(sizeof(int)*M->tu);  
        if(!(num&&cpot)){  
            printf("Apply for memory error.\n");  
            exit(0);  
        }  
        for(col=1;col<=M->nu;col++) num[col]=0;  
        //求M中每一列含有非零元素的个数  
        for(t=1;t<=M->tu;t++)   ++num[M->data[t].j];  
        cpot[1]=1;  
        //求第col列中第一个非零元素在b.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[q].e;  
            ++cpot[col];  
        }//for  
    }//if  
    return OK;  
}  
  
Status MultSMatrix(const TSMatrix *M,const TSMatrix *T,TSMatrix *Q){  
    //稀疏矩阵的乘法,如果符合乘法规则,Q返回M*T结果,并返回OK,否则返回ERROR  
    int i,j,k,p;  
    ElemType m,t,s;  
    if(M->nu!=T->mu){  
        printf("Sorry,these two matrice can't multiply.\n");  
        return ERROR;  
    }  
    Q->mu=M->mu;    Q->nu=T->nu;    Q->tu=0;  
    p=1;  
    for(i=1;i<=Q->mu;i++){  
        for(j=1;j<=Q->nu;j++){  
            s=0;  
            for(k=1;k<=M->nu;k++){  
                if(FALSE==FindElem(M,i,k,&m))  
                    continue;  
                if(FALSE==FindElem(T,k,j,&t))  
                    continue;  
                s+=m*t;  
            }  
            if(s!=0){//Q[i][j]非零  
                Q->data[p].i=i;  
                Q->data[p].j=j;  
                Q->data[p].e=s;  
                p++;  
                Q->tu++;  
            }  
        }  
    }  
  
    return OK;  
  
}  
  
void PrintSMatrix(const TSMatrix *M){  
    //打印稀疏矩阵所有元素  
    int i,j,p=1;  
    printf("\nsize:%d × %d\n",M->mu,M->nu);  
    if(!M->tu){//0矩阵  
        printf("%g\n",0.0);  
        return;  
    }  
    for(i=1;i<=M->mu;i++){  
        for(j=1;j<=M->nu;j++){  
            if(i==M->data[p].i && j==M->data[p].j){  
                printf("%g\t",M->data[p].e);  
                p++;  
            }else{  
                printf("%g\t",0.0);  
            }  
        }  
        printf("\n");  
    }  
    printf("\n");  
}  

*/