数据结构 --- 稀疏矩阵的基本运算

【目的】
领会稀疏矩阵三元组存储结构及其基本算法设计。

【内容】
假设n×n的稀疏矩阵A采用三元组表示,设计一个程序,实现用三元组顺序表存储稀疏矩阵及其基本运算。如下图:(见教材P186:实验题1)。数据结构 --- 稀疏矩阵的基本运算_第1张图片
**【要求】**在主程序中调用算法,输入一个稀疏矩阵,用三元组顺序表存储起来,并能够显示该稀疏矩阵。实现三元组顺序表结构上矩阵的转置、加法和乘法运算。
⑴从键盘输入两个稀疏矩阵的各个元素,然后建立三元组顺序表存储结构。并对该三元组顺序表进行显示。
⑵按照矩阵的列序对矩阵进行转置。
(3)求(1)中输入的两个矩阵的加法运算。
(4)求(1)中输入的两个矩阵的乘法运算。
(5)以上运算的结果均采用三元组输出显示。 程序结构要清晰。数据结构的定义和函数的声明写在头文件(.h)中,函数的实现写在源文件(.c或.cpp)中。

【实现提示】 建立三元组顺序表时,可以用两重循环输入矩阵的每个元素,对元素进行判断,若不为零,则将其行、列下标及其值存入一维数组中; 为了使加法运算的结果矩阵C按行序排列,则应该按照矩阵元素的行列去找A中的三元组,若有,则加入C,同时,这个元素在B中也有,则加上B的这个元素值,否则,这个值就不变;如果A中没有,则找B,有则插入C,无则查找下一个矩阵元素。

# include 
# include 
# define M 4
# define N 4
# define MaxSize 200
# define ElemType int
typedef struct 
{
    int r;//行号
    int c;//列号
    ElemType d;//元素值
}TupNode;

typedef struct 
{
    int rows;//行数
    int cols;//列数
    int nums;//非零个数
    TupNode data[MaxSize];
}TSMatrix;

TSMatrix A,B;

void CreateMat(TSMatrix &t, ElemType A[M][N])
//从一个二维稀疏矩阵创建三元组表示
{
    int i,j;
    t.rows=M; t.cols=N; t.nums=0;
    for(i = 0; i < M; i++ )
    {
        for(j = 0; j < N; j++)
            if(A[i][j]!=0)
            {
                t.data[t.nums].r=i; t.data[t.nums].c=j;
                t.data[t.nums].d=A[i][j]; t.nums++;
            }
    }
}

bool Value (TSMatrix &t, ElemType x, int i, int j)
//三元组的赋值,包括修改值和添加值
{
    int k=0,kl;
    if(i>t.rows||j>t.cols)
        return false;
    while(k<t.nums&&i>t.data[k].r) k++;   //查找i行的非零元素
    while(k<t.nums&&i==t.data[k].r&&j>t.data[k].c) k++;

    if(t.data[k].r==i&&t.data[k].c==j)
        t.data[k].d=x;
    else
    {
        for(kl=t.nums-1;kl>=k;kl--){
            t.data[kl+1].r=t.data[kl].r;
            t.data[kl+1].c=t.data[kl].c;
            t.data[kl+1].d=t.data[kl].d;
        }
        t.data[k].r=i; t.data[k].c=j; t.data[k].d=x;
        t.nums++;
    }
    return true;

}

bool Assign(TSMatrix t,ElemType &x,int i,int j)
{
    int k=0;
    if(i>t.rows||j>t.cols)
        return false;
    while(k<t.nums&&i>t.data[k].r) k++;   //查找i行的非零元素
    while(k<t.nums&&i==t.data[k].r&&j>t.data[k].c) k++;

    if(t.data[k].r==i&&t.data[k].c==j)
        x=t.data[k].d;
    else
        x=0;
    return true;
}

void DispMat(TSMatrix t)
{
    int k;
    if(t.nums<=0)
        return;
    printf("\t%d\t%d\t%d\n",t.rows,t.cols,t.nums);
    printf("\t--------------------------------\t\n");

    for(k=0; k<t.nums; k++)
        printf("\t%d\t%d\t%d\n",t.data[k].r,t.data[k].c,t.data[k].d);
}

void TranTat(TSMatrix t, TSMatrix &tb)  //矩阵的转置函数
{
    int k,k1=0,v;
    tb.rows=t.cols; tb.cols=t.rows; tb.nums=t.nums;

    if(t.nums!=0){
        for(v=0;v<t.cols;v++)
            for(k=0; k<t.nums; k++)
                if(t.data[k].c==v)
                {
                    tb.data[k1].r=t.data[k].c;
                    tb.data[k1].c=t.data[k].r;
                    tb.data[k1].d=t.data[k].d;
                    k1++;
                }
    }
}

void r1()
{
    int a[4][4]={1, 0, 3, 0,
                 0, 1, 0, 0,
                 0, 0, 1, 0,
                 0, 0, 1, 1};
    int b[4][4]={3, 0, 0, 0,
                 0, 4, 0, 0,
                 0, 0, 1, 0,
                 0, 0, 0, 2};
    CreateMat(A,a);
    CreateMat(B,b);
    printf("第一个三元体:\n");
    DispMat(A);
    printf("\n第二个三元体:\n");

    DispMat(B);
}

void r2()
{
    TSMatrix go;
    TranTat(A, go);
    printf("\n矩阵A的转置矩阵如下:\n");
    DispMat(go);
    TranTat(B,go);
    printf("\n矩阵B的转置矩阵如下:\n");
    DispMat(go);

}

void r3()
{
    TSMatrix p;
    int i, j, xa=0, xb=0, sum[M][N]={0};

    for(i=0; i<M; i++)
        for(j=0; j<N; j++)
        {
            Assign(A, xa, i, j);
            Assign(B, xb, i, j);

            if(xa&&xb)
                sum[i][j]=xa+xb;
            else if(xa!=0&&xb==0)
                sum[i][j]=xa;
            else if(xa==0&&xb!=0)
                sum[i][j]=xb;
                
        }

        CreateMat(p,sum);
        printf("矩阵A+B的结果如下:\n");
        DispMat(p);
             
}

void r4()
{
    TSMatrix l;
    int i, j, c, r, xa, xb, res[M][N], re=0;

    for(i=0; i<M; i++)
        for(j=0; j<N; j++)
        {
             for(c=0; c<M; c++)
             {
                 Assign(A,xa,i,c);
                 Assign(B,xb,c,j);
                 re += xa*xb;
             }
             res[i][j]=re;
             re=0;
        }

        CreateMat(l,res);
        printf(" \n乘法的结果如下:\n");
        DispMat(l);
}

void InPut()
{
    int n, i, j,  a[M][N]={0}, b[M][N]={0};
    CreateMat(A,a); CreateMat(B,b);//初始化三元组
    printf("请输入矩阵的行列数N:");
    scanf("%d",&n);
    printf("\n\n请输入第一个矩阵(二维数组形式):");
    
    for(i=0; i<n; i++)
        for(j=0; j<n; j++)
            scanf("%d",&a[i][j]);

            printf("\n\n请输入第二个矩阵(二维数组形式):");
    
    for(i=0; i<n; i++)
        for(j=0; j<n; j++)
            scanf("%d",&b[i][j]);

    CreateMat(A,a);
    CreateMat(B,b);
    printf("\n\n第一个矩阵如下:");
    DispMat(A);
    printf("\n\n第二个矩阵如下:");
    DispMat(B);
}

void Menu()
{
    printf("*******************************\n");
    printf("       稀疏矩阵的运算   \n");
    printf("*******************************\n\n");
    printf("        主菜单               \n");
    printf("     1.输入两个稀疏矩阵       \n");
    printf("     2.求矩阵的转置           \n");
    printf("     3.求矩阵的加法           \n");
    printf("     4.求矩阵的乘法           \n");
    printf("     5.退出系统               \n");
    printf("-------------------------------\n");
}

int main ()
{
    int i=0,j,n;
    Menu();
    printf("请输入你的选择:");
    scanf("%d",&j);

    while(j!=5)
    {
        switch(j) {
            case 1:   r1()        ; break;

            case 2:   r2()        ; break;

            case 3:   r3()        ; break;
            
            case 4:   r4()        ; break;

            default:  break;
        }
        
         printf("\n\n请输入你的选择:"); 
         scanf("%d",&j);
    }
    


    system("pause");
    return 0;
}

/*
请输入第一个矩阵(二维数组形式):
1 0 3 0
0 1 0 0
0 0 1 0
0 0 1 1


请输入第二个矩阵(二维数组形式):
3 0 0 0
0 4 0 0
0 0 1 0
0 0 0 2
*/

你可能感兴趣的:(稀疏矩阵,数据结构,c语言,线性代数)