广东工业大学 数据结构实验报告 题目: 稀疏矩阵

广东工业大学数据结构实验报告         

  题目: 稀疏矩阵 

1.题目: 抽象数据类型稀疏矩阵     ADT 定义如下:

      ADT  SparseMatrix{ 

     数据对象:D={aij| i=1,2,...,m; j=1,2,...,n; 

               aij∈ElemSet, m 和n分别称为矩阵的行数和列数}    

    数据关系:R={Row,Col} 

              Row={| 1<=i<=m,1<=j<=n-1} 

       Col={ | 1<=i<=m-1,1<=j<=n} 

     基本操作:

      Status CreateSMatrix(TSMatrix &M) 

          操作结果:创建稀疏矩阵M 

         Status DestroySMatrix(TSMatrix &M) 

          初始条件:稀疏矩阵M已经存在 

          操作结果:销毁矩阵M 

      void PrintSMatrix(TSMatrix M) 

          初始条件:稀疏矩阵M已经存在 

                操作结果:打印矩阵M

      Status CopySMatrix(TSMatrix M, TSMatrix &T) 

          初始条件:稀疏矩阵M已经存在 

          操作结果:复制矩阵M到T 

      Status AddSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q) 

          初始条件:稀疏数组M、N的行数和列数对应相等 

          操作结果:求矩阵的和Q=M+N 

      Status SubSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q) 

          初始条件:稀疏数组M、N的行数和列数对应相等 

          操作结果:求矩阵的差Q=M-N 

      Status TransposeSMatrix(TSMatrix M, TSMatrix & T) 

          初始条件:稀疏数组M已经存在 

          操作结果:求矩阵M的转置T 

      Status MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q) 

         初始条件:稀疏数组M的列数等于N的行数

                 操作结果:求矩阵的积Q=M*N 

         StatusFindElem(TSMatrix M, int row, int col, ElemType &e)

                     初始条件:稀疏数组M存在

                 操作结果:查找第row行,第col列元素,若不为0则用e返回其值 

         StatusInsertElem(TSMatrix &M, int row, int col, ElemType e)

                     初始条件:稀疏数组M存在

                 操作结果:在第row行,第col列位置插入元素e 

         StatusDeleteElem(TSMatrix &M, int row, int col, ElemType &e)

                     初始条件:稀疏数组M存在

                 操作结果:删除第row行,第col列元素 

         StatusIsEmptyMatrix(TSMatrix M)

                 操作结果:判断是否为空矩阵

       }ADT SparseMatrix

2.存储结构定义

    稀疏矩阵的三元组顺序表存储表示 

       #define MAXSIZE 50

       typedef struct {

            int i, j;

           ElemType e;

       }Triple;

       typedef struct {

          Tripledata[MAXSIZE+1];                   

       intmu, nu, tu;

       }TSMatrix;

 

3. 算法设计

#include

#include

#define TRUE 1;

#define FALSE 0;

#define OK 1

#define ERROR 0;

typedef intStatus;

typedef intElemType;                                                                       

/*  稀疏矩阵的三元组顺序表存储表示  */

#define MAXSIZE 50

typedef struct {

    int i, j;

    ElemType e;

}Triple;

typedef struct {

    Triple data[MAXSIZE+1];            //这里可用数组实现也可用指针实现

    int mu, nu, tu;

}TSMatrix;

//对三元组表示的稀疏矩阵进行排序

                      //需要排序是因为创建三元组时可以任意不按顺序输入

voidOrder(TSMatrix &M){

    int a, b;

    Triple t;

    for(a=1; a

        for(b=a+1; b

            if(M.data[a].i > M.data[b].i){        //如果前面一个行号比后面一                                                                                      //个行号大,就交换

                t = M.data[a];

                M.data[a] = M.data[b];

                M.data[b] = t;

            }

            if(M.data[a].i ==M.data[b].i){        //行号相等,列号大的在后面

                if(M.data[a].j >M.data[b].j){

                    t = M.data[a];

                    M.data[a] = M.data[b];

                    M.data[b] = t;

                }   

            }

        }     

    }          

}

//销毁稀疏矩阵M 

StatusDestroySMatrix(TSMatrix &M){         //要想销毁一个三元组表示的                                                                                          //矩阵就必须销毁四部分

    int num = M.tu;                          //M.mu,M.nu,M.tu和M.data[]

    M.mu = 0;

    M.nu = 0;

    M.tu = 0;

    for(int k=1; k<=num; k++){            //因为用数组实现,又数组为静                                                                 // 态分配,故销毁数组只能置其内容为0

        M.data[k].i = 0;             // 而不能释放其空间

        M.data[k].j = 0;

        M.data[k].e = 0;

    }

    return OK;

}        

//创建稀疏矩阵M

StatusCreateSMatrix(TSMatrix &M){

   if(M.tu != 0)                                       //M如果非空

              DestroySMatrix(M);

    int m, n, t, i, j, e;

    int flag = 0;                               //flag用来标志输入是否重复

    printf("请输入矩阵的行数、列数和非零元个数(格式为:X,X,X)\n");

    while(1){

        scanf("%d,%d,%d",&m,&n,&t);

        if(t<=0 || m<=0 || n<=0){                   //输入的行列数要为整数

             printf("对不起,您输入有误!请重新输入!\n");

             printf("请输入矩阵的行数、列数和非零元个数(格式为:X,X,X)\n");            

        }else if(t > m*n){               //非零元个数不能大于矩阵最大个数

             printf("对不起,您输入的非零元个数不合理!请重新输入!\n");

             printf("请输入矩阵的行数、列数和非零元个数(格式为:X,X,X)\n");           

        }else                                           //输入正确

            break;       

    }

    M.mu = m; M.nu = n; M.tu = t;  

    printf("请输入你想创建的稀疏矩阵:(格式为:X,X,X)\n");    

    for(int k=1; k<=M.tu; k++){

        scanf("%d,%d,%d",&i,&j,&e);

        if(i > M.mu){

            printf("输入有误,行号过大,请重新输入!\n");

            k--;

        }else if(i <= 0){

             printf("输入有误,行号必须为正数,请重新输入!\n");

             k--;

        }else if(j <= 0){

             printf("输入有误,列号必须为正数,请重新输入!\n");

             k--;

        }else if(j > M.nu){

            printf("输入有误,列号过大,请重新输入!\n");

            k--;

        }else if(e == 0){

            printf("输入有误,值不能为零,请重新输入!\n");

            k--;

        }else {               

            for(int t=1; t<=k; t++){

                if(i==M.data[t].i &&j==M.data[t].j){

                    printf("输入有误,您输入的下标重复,请重新输入!\n");

                    k--;

                    flag = 1;

                    break;

                }                                  

            }

            if(flag == 0){                   //输入完全正确情况下

                M.data[k].i = i;

                M.data[k].j = j;

                M.data[k].e = e;

            }   

        }                   

    }

    //对三元组表示的稀疏矩阵进行排序 

    Order(M);

    printf("*矩阵已完成创建!*\n");

    return OK;

}                                   

//输出稀疏矩阵M

voidPrintSMatrix(TSMatrix M){                                      

    printf("\t-----------------");

    printf("\n");

   printf("\t%c\t%c\t%c",'i','j','e');

    printf("\n");

    printf("\t-----------------");

    printf("\n");

    if(M.tu == 0)                                    //如果为空

        printf("\t这是一个空的矩阵\n");

    else{   

        for(int k=1; k<=M.tu; k++){     

            printf("\t%d\t%d\t%d",M.data[k].i,M.data[k].j,M.data[k].e);

            printf("\n");

        }

    }    

    printf("\t-----------------");

    printf("\n\n");

}

//查找三元组表示的稀疏矩阵M中,第row行,第col列元素,若不为0则用e返回其值

StatusFindElem(TSMatrix M, int row, int col, ElemType &e){   

    for(int k=1; k<=M.tu; k++){

        if(row==M.data[k].i &&col==M.data[k].j){

            e = M.data[k].e;

            printf("*元素已找到:*\n");

            printf("%d\n", e);

            return OK;

        }

    }                                              //找不到

    printf("对不起,不存在此元素!\n");

    return ERROR;  

}

//在三元组表示的稀疏矩阵M,第row行,第col列位置插入元素e

StatusInsertElem(TSMatrix &M, int row, int col, ElemType e){

    int i, t, p;  

    if(M.tu >= MAXSIZE){                           //当前三元组表已满

        printf("当前三元组表已满,操作失败!\n");

        return ERROR; 

    } 

    if(row>M.mu || col>M.nu || row<1|| col<1){          //插入位置越界,                                                                                         //     不在1~mu或1~nu之间

        printf("插入位置越界,请在此矩阵的行列数内操作。操作失败!\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++;

        printf("*元素已插入!*\n");

        return OK; 

    }                            

    for(t=1; t<=M.tu; t++){                              //寻找合适的位置

        if(row > M.data[t].i)

            p++;

        else if((row==M.data[t].i) &&(col>=M.data[t].j))

            p++;

        else if((row==M.data[t].i) &&(col==M.data[t].j)){       //插入前,该位                                                                                                     //     置元素已经存在

            M.data[t].e=e;

            printf("*元素已插入!*\n");

            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++;

    printf("*元素已插入!*\n");

    return OK;

}

//在三元组表示的稀疏矩阵M,删除第row行,第col列位置元素,并用e返回

StatusDeleteElem(TSMatrix &M, int row, int col, ElemType &e){

    int i, t, p=0;

    if(M.tu == 0){                                      //矩阵如果为空

        printf("操作失败!这是个空矩阵!\n");

        return ERROR;

    }

    if(row>M.mu || col>M.nu || row<1|| col<1){      //删除位置越界,不在1~mu                                                                                     //     或1~nu之间

        printf("删除位置越界,请在此矩阵的行列数内操作。操作失败!\n");

        return ERROR; 

    }                                              

    for(t=1; t<=M.tu; t++){                           //寻找合适的删除位置

        if((row==M.data[t].i) &&(col==M.data[t].j))

            p = t;

    }

    if(p == 0){

         printf("删除失败,不存在此元素!\n");

         return ERROR;  

    }else{

        e = M.data[p].e;

        for(; p

            M.data[p].i = M.data[p+1].i;

            M.data[p].j = M.data[p+1].j;

            M.data[p].e = M.data[p+1].e;

        }

        M.data[p].i = 0;                   //把最后一个元素置为0

        M.data[p].j = 0;

        M.data[p].e = 0;

    }       

    M.tu--;

    printf("*元素已删除: *\n");

    printf("%d\n", e);

    return OK;         

}

//判断是否为空矩阵

StatusIsEmptyMatrix(TSMatrix M){

    if(M.tu == 0){

        printf("*这是一个空矩阵!*\n");

    }else

        printf("*这是一个非空矩阵!*\n");

    return OK;

}

//由稀疏矩阵M复制得到T

Status CopySMatrix(TSMatrixM, TSMatrix &T){

    if(T.tu != 0)                       //原来T为非空

        DestroySMatrix(T);

    T.mu = M.mu;

    T.nu = M.nu;

    T.tu = M.tu;

    for(int k=1; k<=M.tu; k++){

        T.data[k].i = M.data[k].i;

        T.data[k].j = M.data[k].j;

        T.data[k].e = M.data[k].e;

    }   

    return OK;

}

//求和Q = M + N

StatusAddSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q){

    ElemType t;

    int k=1, a, b;              // a,b记下已经访问了几个

    int flag[50];              //flag用来标志 N 表中哪个数据已经用过

    if(Q.tu != 0)                       //原来Q为非空

        DestroySMatrix(Q);

    if(M.tu == 0){

        CopySMatrix(N, Q);

        printf("*矩阵已完成相加!*\n");

        return OK;

    }else if(N.tu == 0){

        CopySMatrix(M, Q);

        printf("*矩阵已完成相加!*\n");

        return OK;

    } 

    if(M.mu!=N.mu || M.nu!=N.nu){

        printf("对不起,两个矩阵的行列号大小不相等不能相加!\n");

        return ERROR;

    }       

    Q.mu = M.mu; Q.nu = M.nu;

    a = 0; b = 0;  

    for(int x=1; x<=49; x++)

        flag[x] = 0;

    for(int p1=1; p1<=M.tu; p1++){       

        for(int p2=1; p2<=N.tu; p2++){

            if(M.data[p1].i ==N.data[p2].i){         //行号相等

                if(M.data[p1].j ==N.data[p2].j){      //且列号相等

                    flag[p2] = 1;              //为 1 表示此数据已经用过

                    a++; b++;                     //M, N访问数各加1

                    t = M.data[p1].e +N.data[p2].e;

                    if(t != 0){                       //和为非零,插入

                        Q.data[k].i =M.data[p1].i;

                        Q.data[k].j = M.data[p1].j;

                        Q.data[k].e = t;

                        k++;

                        break;

                    }else

                        break;

                }

                else{               //行号相等,列号不等,把列号小的插入

                    if(M.data[p1].j

                        Q.data[k].i =M.data[p1].i;

                        Q.data[k].j =M.data[p1].j;

                        Q.data[k].e =M.data[p1].e;

                        flag[p2] = 0;

                        k++; a++;

                        break;

                    }else if(flag[p2] ==0){         //N表中此数据还没访问                                                                                       //     过且列号小,插入

                        Q.data[k].i =N.data[p2].i;

                        Q.data[k].j =N.data[p2].j;

                        Q.data[k].e =N.data[p2].e;

                        flag[p2] = 1;

                        k++; b++;

                    }                   

                }               

            }

            else{                            //行号不等,把行号小的插入

                if(M.data[p1].i

                    Q.data[k].i = M.data[p1].i;

                    Q.data[k].j = M.data[p1].j;

                    Q.data[k].e = M.data[p1].e;

                    a++; k++;

                    break;

                }

                else if(flag[p2] == 0){

                    Q.data[k].i = N.data[p2].i;

                    Q.data[k].j = N.data[p2].j;

                    Q.data[k].e = N.data[p2].e;

                    flag[p2] = 1;

                    k++; b++;

                }

            }  

        }       

    }                 

    if(a

        while(a

            Q.data[k].i = M.data[a+1].i;

            Q.data[k].j = M.data[a+1].j;

            Q.data[k].e = M.data[a+1].e;

            k++; a++;

        }

    }else if(b

        while(b

            Q.data[k].i = N.data[b+1].i;

            Q.data[k].j = N.data[b+1].j;

            Q.data[k].e = N.data[b+1].e;

            k++; b++;           

        }

    }       

    Q.tu = k-1;

    printf("*矩阵已完成相加!*\n");

    return OK;

}

//求差Q = M - N

StatusSubSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q){

    ElemType t;

    int k=1, a, b;              // a,b记下已经访问了几个

    int flag[50];              //用来标志 N 表中哪个数据已经用过

    if(Q.tu != 0)                       //原来Q为非空

        DestroySMatrix(Q);

    if(M.tu == 0){                         //被减数为空

        CopySMatrix(N, Q);

        for(int k=1; k<=N.tu; k++)

            Q.data[k].e = -Q.data[k].e;    //变为负的

        printf("*矩阵已完成相减!*\n");

        return OK;

    }else if(N.tu == 0){                  //减数为空

        CopySMatrix(M, Q);

        printf("*矩阵已完成相减!*\n");

        return OK;

    }

    if(M.mu!=N.mu || M.nu!=N.nu){

        printf("对不起,两个矩阵的行列号大小不相等不能相减!\n");

        return ERROR;

    }      

    Q.mu = M.mu; Q.nu = M.nu;

    a = 0; b = 0;  

    for(int x=1; x<=49; x++)

        flag[x] = 0;

    for(int p1=1; p1<=M.tu; p1++){  

        for(int p2=1; p2<=N.tu; p2++){                

            if(M.data[p1].i ==N.data[p2].i){           //行号相等  

                if(M.data[p1].j ==N.data[p2].j){       //且列号相等

                    flag[p2] = 1;              //为 1 表示此数据已经用过

                    a++; b++;                     //M, N访问数各加1

                    t = M.data[p1].e -N.data[p2].e;

                    if(t != 0){                         //差为非零,插入

                        Q.data[k].i =M.data[p1].i;

                        Q.data[k].j = M.data[p1].j;

                        Q.data[k].e = t;

                        k++;

                        break;

                    } else break;

                }                  //行号相等,列号不等,把列号小的插入

                else{

                    if(M.data[p1].j

                        Q.data[k].i =M.data[p1].i;

                        Q.data[k].j =M.data[p1].j;

                        Q.data[k].e =M.data[p1].e;

                        flag[p2] = 0;

                        k++; a++;

                        break;

                    }else if(flag[p2] ==0){      //N表中此数据还没访问过                                                                                                且列号小,插入

                        Q.data[k].i =N.data[p2].i;

                        Q.data[k].j =N.data[p2].j;

                        Q.data[k].e =-N.data[p2].e;  //减数要变为负的

                        flag[p2] = 1;

                        k++; b++;

                    }                   

                }               

            }

            else{                            //行号不等,把行号小的插入

                if(M.data[p1].i

                    Q.data[k].i = M.data[p1].i;

                    Q.data[k].j = M.data[p1].j;

                    Q.data[k].e = M.data[p1].e;

                    a++; k++;

                    break;

                }

                else if(flag[p2] == 0){

                    Q.data[k].i = N.data[p2].i;

                    Q.data[k].j = N.data[p2].j;

                    Q.data[k].e =-N.data[p2].e;

                    flag[p2] = 1;

                    k++; b++;

                }

            }  

        }       

    }                 

    if(a

        while(a

            Q.data[k].i = M.data[a+1].i;

            Q.data[k].j = M.data[a+1].j;

            Q.data[k].e = M.data[a+1].e;

            k++; a++;

        }

    }else if(b

        while(b

            Q.data[k].i = N.data[b+1].i;

            Q.data[k].j = N.data[b+1].j;

            Q.data[k].e = -N.data[b+1].e;

            k++; b++;           

        }

    }       

    Q.tu = k-1;  

    printf("*矩阵已完成相减!*\n");

    return OK;

}

//求积Q = M * N

StatusMultSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q){

    if(M.nu != N.mu){

        printf("操作失败!第一个矩阵的列数不等于第二个矩阵的行数!\n");

        return ERROR;

    }

    int a[10][10];                              //先用数组将结果保存

    int t = 1;

    if(Q.tu != 0)                       //原来Q为非空

        DestroySMatrix(Q);

    Q.mu = M.mu; Q.nu = N.nu; Q.tu = 0;

    for(int k=1; k<=M.tu; k++){

        for(int p=1; p<=N.tu; p++){

            if(M.data[k].j ==N.data[p].i){    //凡是第一个矩阵的列号等于第                                                                    //       二个矩阵的行号的都把结果相加

                                                                      //       分别放入以第一个矩阵行号为i

                                                                       //     第二个矩阵列号为j的数组中

                a[M.data[k].i][N.data[p].j] +=M.data[k].e * N.data[p].e;        

            }                                                             

        }

    }

    for(int m=1; m<10; m++){                    //放入Q中

        for(int n=1; n<10; n++){

            if(a[m][n] != 0){

                Q.data[t].e = a[m][n];

                Q.data[t].i = m;

                Q.data[t].j = n;

                t++;

            }

        }

    }

    Q.tu = t - 1;   

    printf("*矩阵已完成相乘*\n");

    return OK;

}

//由稀疏矩阵M的转置矩阵T

StatusTransposeSMatrix(TSMatrix M, TSMatrix &T){       //快速转置

    int col, t, p, q;

    int num[50], cpot[50], data[50];

    if(T.tu != 0)

        DestroySMatrix(T);                       //原来T为非空

    T.mu = M.mu;

    T.nu = M.nu;

    T.tu = M.tu;

    if(T.tu){

        for(col=1; col<=M.nu; col++)

            num[col] = 0;          //初始化为0       

        for(t=1; t<=M.tu; t++)

            ++num[M.data[t].j];     //求M中每一列含非零元素个数

        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

        }

    }

    printf("*矩阵已完成转置!*\n");

    return OK;

}                                               

//设计者信息

void Designer(){

    printf("\t\t    Design By XXX\n");

    printf("\t\t_______________________\n");

    printf("\t\t|   姓名 : |  XXX   |\n");

   printf("\t\t|-----------------------\n");

    printf("\t\t|   班级:  |  计科1    |\n");

   printf("\t\t|-----------------------\n");

    printf("\t\t|   学号:  | 3112005763|\n");

    printf("\t\t~~~~~~~~~~~~~~~~~~~~~~~\n");

    printf("\tCopyright @CKW, All RightsReserved\n\n");

}

//欢迎界面

void Welcome(){

    printf("\t\t欢迎来到《稀疏矩阵》中心!\n");

    printf("\t\t请输入你想要进行的操作:\n");

    printf("\ta.【创建稀疏矩阵】b.【输出稀疏矩阵】 c.【转置稀疏矩阵】\n");

    printf("\td.【插入元素】\t   e.【删除元素】\tf.【查找元素】\n");

    printf("\tg.【矩阵相加】\t   h.【矩阵相减】\ti.【矩阵相乘】\n");

    printf("\tj.【矩阵判空】\t   k.【销毁矩阵】\tl.【矩阵复制】\n");

    printf("\t\t\t0.【退出系统!】\n\n");

   

}

//主函数

void main()

{                      

    TSMatrix M, T, N, Q;   

    int row, col;

    char c, n;

    ElemType e;

    Designer();

    Welcome();   

    while(1){

        printf("【请输入你想要进行的操作:】\n");

        scanf(" %c", &n);      //此处输入的是字符,因为字符比数字容易处理

                            // %c前面有个空格是因为scanf()的缓冲区处理

        if(n == '0')                       //如果输入0字符即退出系统

            break;                               //a ~ l之间

        else if('a'<=n &&n<='l'){

            switch(n){            

                case 'a': {

                        printf("请选择你想要创建哪个矩阵:\n");

                        printf("请输入 M 或者 N \n");

                        while(1){

                            scanf("%c", &c);

                            if(c == 'M'){

                               CreateSMatrix(M); break;

                            }else if(c == 'N'){

                               CreateSMatrix(N); break;

                            }else{

                                 printf("你输入有误,请重新输入!\n");

                            }                   

                        }

                        break;

                }

                case 'b': {

                        printf("请选择你想要输出的矩阵:\n");

                        printf("M(原矩阵)N(原矩阵)T(复制or转置矩阵)Q(运                                                                                                     算后的矩阵)\n");

                        while(1){

                            scanf("%c", &c);                      

                            if(c == 'M'){

                               PrintSMatrix(M); break;

                            }else if(c == 'N'){

                               PrintSMatrix(N); break;

                            }else if(c == 'T'){

                               PrintSMatrix(T); break;

                            }else if(c == 'Q'){

                                PrintSMatrix(Q); break;

                            }else{

                                 printf("你输入有误,请重新输入!\n");

                            }                   

                        }

                        break;

                }

                case 'c': {

                        printf("请选择你想要转置的矩阵:\n");

                        printf("请输入 M 或者 N 或者Q\n");

                        while(1){

                            scanf("%c", &c);                      

                            if(c == 'M'){

                               TransposeSMatrix(M, T); break;

                            }else if(c == 'N'){

                               TransposeSMatrix(N, T); break;

                            }else if(c == 'Q'){

                                TransposeSMatrix(Q, T);break;

                            }else{

                                 printf("你输入有误,请重新输入!\n");

                            }                   

                        }

                        break;

                }

                case 'd': {

                        printf("请选择你想要插入元素的矩阵:\n");

                        printf("请输入 M 或者 N 或者 Q 或者 T\n");

                        while(1){

                            scanf("%c", &c);                      

                            if(c == 'M'){

                                printf("请输入你想要插入元素的位置及该                                                                          元素(X,X,X):\n");

                               scanf("%d,%d,%d", &row, &col, &e);

                                InsertElem(M,row, col, e); break;

                            }else if(c == 'N'){

                                printf("请输入你想要插入元素的位置及该                                                                          元素(X,X,X):\n");

                               scanf("%d,%d,%d", &row, &col, &e);

                                InsertElem(N,row, col, e); break;

                            }else if(c == 'Q'){

                                printf("请输入你想要插入元素的位置及该                                                                          元素(X,X,X):\n");

                               scanf("%d,%d,%d", &row, &col, &e);

                                InsertElem(Q,row, col, e); break;

                            }else if(c == 'T'){

                                printf("请输入你想要插入元素的位置及该                                                                          元素(X,X,X):\n");

                               scanf("%d,%d,%d", &row, &col, &e);

                                InsertElem(T,row, col, e); break;

                            }else{

                                 printf("你输入有误,请重新输入!\n");

                            }                   

                        }

                        break;

                }

                case 'e': {

                        printf("请选择你想要删除元素的矩阵:\n");

                        printf("请输入 M 或者 N 或者 Q 或者 T\n");

                        while(1){

                            scanf(" %c",&c);                      

                            if(c == 'M'){

                           printf("请输入你想要删除元素的位置(X,X):\n");

                               scanf("%d,%d", &row, &col);

                                DeleteElem(M,row, col, e); break;

                            }else if(c == 'N'){

                           printf("请输入你想要删除元素的位置(X,X):\n");

                               scanf("%d,%d", &row, &col);

                                DeleteElem(N,row, col, e); break;

                            }else if(c == 'Q'){

                           printf("请输入你想要删除元素的位置(X,X):\n");

                               scanf("%d,%d", &row, &col);

                                DeleteElem(Q,row, col, e); break;

                            }else if(c == 'T'){

                           printf("请输入你想要删除元素的位置(X,X):\n");

                               scanf("%d,%d", &row, &col);

                                DeleteElem(T,row, col, e); break;

                            }else{

                                 printf("你输入有误,请重新输入!\n");

                            }                   

                        }

                        break;

                }           

                case 'f': {

                        printf("请选择你想要查找元素的矩阵:\n");

                        printf("请输入 M 或者 N 或者 Q 或者 T\n");

                        while(1){

                            scanf("%c", &c);                      

                            if(c == 'M'){

                           printf("请输入你想要查找元素的位置(X,X):\n");

                               scanf("%d,%d", &row, &col);

                                FindElem(M,row, col, e); break;

                            }else if(c == 'N'){

                           printf("请输入你想要查找元素的位置(X,X):\n");

                               scanf("%d,%d", &row, &col);

                                FindElem(N,row, col, e); break;

                            }else if(c == 'Q'){

                           printf("请输入你想要查找元素的位置(X,X):\n");

                                scanf("%d,%d",&row, &col);

                                FindElem(Q,row, col, e); break;

                            }else if(c == 'T'){

                           printf("请输入你想要查找元素的位置(X,X):\n");

                               scanf("%d,%d", &row, &col);

                                FindElem(T,row, col, e); break;

                            }else{

                                 printf("你输入有误,请重新输入!\n");

                            }                    

                        }

                        break;

                }                      

                case'g':AddSMatrix(M,N,Q);break;                                                                                                //只能是M和N相加,相减,相乘

                case 'h': SubSMatrix(M, N, Q);break;

                case 'i': MultSMatrix(M, N, Q);break;

                case 'j': {

                        printf("请选择你想要判空的矩阵:\n");

                        printf("请输入 M 或者 N 或者 Q 或者 T\n");

                        while(1){

                            scanf("%c", &c);                      

                            if(c == 'M'){

                               IsEmptyMatrix(M); break;

                            }else if(c == 'N'){

                                IsEmptyMatrix(N); break;

                            }else if(c == 'Q'){

                               IsEmptyMatrix(Q); break;

                            }else if(c == 'T'){

                               IsEmptyMatrix(T); break;

                            }else{

                                 printf("你输入有误,请重新输入!\n");

                            }                   

                        }

                        break;

                }                                 

                case 'k': {

                        printf("请选择你想要销毁的矩阵:\n");

                        printf("请输入 M 或者 N 或者 Q 或者 T\n");

                        while(1){

                            scanf("%c", &c);                      

                            if(c == 'M'){

                               DestroySMatrix(M);

                                printf("*矩阵已完成销毁!*\n");                                                               //把打印语句写在这里而不写在函数里是因为

                                                    //别的函数会用到这个函数,避免多余的麻烦

                                break;                                

                            }else if(c == 'N'){

                               DestroySMatrix(N);

                                printf("*矩阵已完成销毁!*\n");

                                break;

                            }else if(c == 'Q'){

                               DestroySMatrix(Q);

                                printf("*矩阵已完成销毁!*\n");

                                break;

                            }else if(c == 'T'){

                               DestroySMatrix(T);

                                printf("*矩阵已完成销毁!*\n");

                                break;

                            }else{

                                 printf("你输入有误,请重新输入!\n");

                            }                   

                        }

                        break;

                }                                        

                case 'l': {

                        printf("请选择你想要复制哪个矩阵:\n");

                        printf("请输入 M 或者 N 或者Q\n");

                        while(1){

                            scanf("%c", &c);

                            if(c == 'M'){

                                CopySMatrix(M,T);

                                printf("*矩阵已完成复制!*\n");                                                        //把打印语句写在这里而不写在函数里是因为

                                                 //别的函数会用到这个函数,避免多余的麻烦

                                break;                                

                            }else if(c == 'N'){

                                CopySMatrix(N,T);

                                printf("*矩阵已完成复制!*\n");

                                break;

                            }else if(c == 'Q'){

                                CopySMatrix(Q,T);

                                printf("*矩阵已完成复制!*\n");

                                break;

                            }else{

                                 printf("你输入有误,请重新输入!\n");

                            }                   

                        }

                        break;

                }

               

                default: break;

            }                

        }else{

            printf("对不起,您输入的操作有误,请重新输入!\n");

        }   

    }

    printf("\t\t\t已安全退出,感谢使用!\n");              

}

 

4.调试与分析

问题1:

       创建三元组时,为了可以满足任意输入的无序数据也能构成三元组

       解决方法:对三元组表示的稀疏矩阵进行排序               

                        调用方法voidOrder(TSMatrix &M)

问题2:

       创建稀疏矩阵时,为了满足输入的容错性

       解决方法:使用了循环的方法while( 1 ){ 输入正确时跳出循环 }

问题3:

       如何销毁稀疏矩阵

       解决方法:要想销毁一个三元组表示的矩阵就必须销毁四部分:1.M.mu,                                   2.M.nu,   3.M.tu  4.M.data[]

                        可以将M.mu, M.nu, M.tu置为0即可销毁 M.mu, M.nu, M.tu

                      因为M.data[]用数组实现,又数组为静态分配,故销毁数组只能                            置其内容为0,而不能释放其空间。所以利用

              for(int k=1; k<=num;k++){                     

                                    M.data[k].i = 0;                           

                                    M.data[k].j = 0;

                             M.data[k].e= 0;

                      }将M.data[]置为0即可销毁之

问题4:

       如何在矩阵中插入新元素

       解决方法:先找到要插入的行列号在三元组中的位置,然后向后移动此位置                  以后的所有元素,再插入。

问题5:

       如何进行矩阵求和。

       解决方法:分为3大类。1,行号不相等的,把行号小的插入。2,行号相等                      而列号不相等的,把列号小的插入。3,行列号都相等的,求和                                 后如果非零即插入。最后,如果M表未完,即把剩下的插入。                              如果N表未完,即把剩下的插入。

问题6:

       如何进行矩阵相乘。

       解决方法:先用数组将结果保存,再用数组逐一给三元组赋值。也即是,凡                      是第一个矩阵的列号等于第二个矩阵的行号的都把结果相乘,分                        别放入以第一个矩阵行号为i第二个矩阵列号为j的数组a[i][j]                              中,再用数组逐一给三元组赋值。

问题7:

       矩阵如何进行快速转置。

       解决方法: 先计算出矩阵M中的每一列的第一个非零元素在T.data中的位                              置,再进行相应插入。

问题8:

       scanf函数输入时键盘缓冲区\n的问题。也即对于scanf("%c", &j)来说,回

    车键也作为一种输入。当我上一行有回车时,使用scanf("%c", &j)出现问题。

 

    解决方法:可以用scanf("%c", &j)来解决。注意%c前面有一个空格。这个             空格有吸收回车和空格的功能,吸收之后要求buffer给一个字节,直到这个字节不是回车或空格,此时把这个字节交给下一个格式串。问题解决。

5.运行测试

请读者自行测试。

 

你可能感兴趣的:(IT,广工,数据结构,实验报告)