精华内容
下载资源
问答
  • 内蒙古科技大学 数据结构课程设计说明书 题 目稀疏矩阵运算器设计 学生姓名 学 号 专 业计算机科学与技术 班 级计 09-1 班 指导教师刘 月 峰 2011 年 6 月 24 日 稀疏矩阵运算器设计 摘 要 摘要设计一稀疏矩阵运算器...
  • 稀疏矩阵运算器

    2017-03-14 22:48:22
    printf("输入稀疏矩阵A的行数,列数和非零元个数:"); scanf("%d %d %d",&A.m,&A.n,&A.t); for(k=1;k;k++) { printf("输入第%d个非0元素的行数,列数和值:",k); scanf("%d %d %d",&A.data[k].i,&A.data[k].j,&...
  • 输入要求:稀疏矩阵的行、列和非零元素个数 以及每个非零元素在矩阵的位置 以三元组格式存储稀疏矩阵 输出要求:根据选项输出 稀疏矩阵的转置、加法、减法、乘法
  • 内蒙古科技大学 数据结构课程设计说明书 题 目稀疏矩阵运算器设计 学生姓名 学 号 专 业计算机科学与技术 班 级计 09-1 班 指导教师刘 月 峰 2011 年 6 月 24 日 稀疏矩阵运算器设计 摘 要 摘要设计一稀疏矩阵运算器...
  • 题目:设计一个程序,实现一个能进行稀疏矩阵基本运算的计算器。按照教科书《数据结构(C语言版)》(严蔚敏等)5.3.2节中描述的方法,以十字链表表示稀疏矩阵。一、需求分析稀疏矩阵是指那些多数元素为零的矩阵。利用...

    题目:设计一个程序,实现一个能进行稀疏矩阵基本运算的计算器。按照教科书《数据结构(C语言版)》(严蔚敏等)5.3.2节中描述的方法,以十字链表表示稀疏矩阵。

    一、需求分析

    稀疏矩阵是指那些多数元素为零的矩阵。利用“稀疏”特点进修学校储存和计算可以大大节省储存空间,提高计算效率。实现一个能进行稀疏矩阵基本运算的计算器。

    以“带行逻辑链接信息”的三元组顺序表表示稀疏矩阵,实现两个矩阵相加、相减和相乘的运算。稀疏矩阵的输入形式采用三元组表示,而运算结果的矩阵则以通常的阵列形式列出。

    测试数据

    \left[ \begin{matrix} 10&0& 0 \\ 0&0&9 \\ -1&0&0 \\ \end{matrix}\right] + \left[ \begin{matrix} 0&0& 0 \\ 0&0&-1 \\ 1&0&-3 \\ \end{matrix}\right]= \left[ \begin{matrix} 10&0& 0 \\ 0&0&8 \\ 0&0&-3 \\ \end{matrix}\right]

    \left[ \begin{matrix} 10&9 \\ 0&9 \\ -1&0 \\ \end{matrix}\right] - \left[ \begin{matrix} 0&0 \\ 0&-1 \\ 1&-3 \\ \end{matrix}\right]= \left[ \begin{matrix} 10&0 \\ 0&10 \\ -2&-3 \\ \end{matrix}\right]

    \left[ \begin{matrix} 4&-3&0&0&1 \\ 0&0&0&8&0 \\ 0&0&1&0&0 \\ 0&0&0&0&0 \end{matrix}\right] \times \left[ \begin{matrix} 3&0&0 \\ 4&2&0 \\ 0&1&0 \\ 1&0&0 \\ 0&0&0 \end{matrix}\right] = \left[ \begin{matrix} 0&-6&0 \\ 8&0&0 \\ 0&1&0 \\ 0&0&0 \end{matrix}\right]

    二、概要设计

    1.数据结构

    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 }

    基本操作:

    CreateSMatrix(&M)

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

    PrintSMatrix(M)

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

    操作结果: 输出稀疏矩阵M。

    AddSMatrix(M, N, &Q)

    初始条件:稀疏矩阵M与N的行数和列数对应相等。

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

    SubtSMatrix(M, N, &Q)

    初始条件:稀疏矩阵M与N的行数和列数对应相等。

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

    MultSMatrix(M, N, &Q)

    初始条件:稀疏矩阵M的列数等于N的行数。

    操作结果:求稀疏矩阵乘积Q=M*N。

    }ADT SparseMatrix

    2. 使用函数

    (1)行逻辑链接的顺序表

    int CreateSMatrix(RLSMatrix *M)

    操作结果:创建稀疏矩阵

    int PrintSMatrix(RLSMatrix M)

    操作结果:打印稀疏矩阵

    int AddSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix *Q)

    操作结果:稀疏矩阵加法,Q=M+N

    int SubSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix *Q)

    操作结果:稀疏矩阵减法,Q=M-N

    int MultSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix *Q)

    操作结果:稀疏矩阵乘法,Q=M*N

    (2)十字链表

    int CreateSMatrix_OL(CrossList *M)

    操作结果:创建稀疏矩阵

    int PrintSMatrix_OL(CrossList M)

    操作结果:打印稀疏矩阵

    int AddSMatrix_OL(CrossList *A, CrossList *B)

    操作结果:将稀疏矩阵B加到稀疏矩阵A上

    int SubSMatrix_OL(CrossList *A, CrossList *B)

    操作结果:在稀疏矩阵A上减去稀疏矩阵B

    int MultSMatrix_OL(CrossList A, CrossList B, CrossList *C)

    操作结果:稀疏矩阵乘法,C=A*B

    三、详细设计

    1. 数据储存结构

    (1)行逻辑链接顺序表

    #define MAXSIZE 400 // 最大非零元个数

    #define MAXRC 20 // 最大行数和列数

    typedef struct{

    int i,j; // 该非零元的行下标和列下标

    int e;

    }Triple;

    typedef struct{

    Triple data[MAXSIZE+1]; // 非零元三元组表

    int rpos[MAXRC+1]; // 各行第一个非零元位置表

    int mu,nu,tu; // 矩阵行数、列数和非零元个数

    }RLSMatrix;

    (2)十字链表

    #define MAXSIZE 400 // 最大非零元个数

    #define MAXRC 20 // 最大行数和列数

    typedef struct OLNode{

    int i,j; // 该非零元的行和列下标

    int e;

    struct OLNode *right, *down; // 该非零元所在行表和列表的后继链域

    }OLNode, *OLink;

    typedef struct {

    OLink *rhead, *chead; // 行和列链表头指针向量基址由CreateSMatrix分配

    int mu, nu, tu; // 稀疏矩阵行数、列数和非零元个数

    }CrossList;

    2.基本功能实现

    2.1行逻辑链接顺序表

    (1)稀疏矩阵创建

    分别读入矩阵行数、列数以及非零元个数,同时提示输入各个非零元位置和数值,对于输入的非零元判断是否合法,并根据行号和列号进行以行为主序的储存,最后计算各行首个非零元位置。

    int CreateSMatrix(RLSMatrix *M){

    if(M) free(M);

    int m,n,t;

    do{

    printf("输入矩阵行数,列数和非零元数目,用空格隔开\n");

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

    if(m < 0 || n < 0 || t < 0 || t > m*n){

    printf("参数错误 \n");

    }

    }while(m < 0 || n < 0 || t < 0 || t > m*n);

    M->mu = m; M->nu = n; M->tu = t;

    printf("请按行优先输入三元组\n");

    int i,j,e,k;

    int p,q;

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

    do{

    printf("输入第%d个非零元的行号 列号 值, 用空格隔开\n",k);

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

    if(i <= 0 || j <= 0 || i > m || j > n|| e==0){

    printf("参数错误\n");

    }

    }while(i <= 0 || j <= 0 || i > m || j > n|| e==0);

    for(p = 1; p <= k-1 && (i > M->data[p].i || (i == M->data[p].i && j > M->data[p].j)); p++); //找到三元组插入的位置

    for(q = k-1;q >= p; q--) M->data[q+1] = M->data[q]; //行序大的三元组依次向后移动

    M->data[p].i = i;

    M->data[p].j = j;

    M->data[p].e = e;

    }

    int row,x;

    int num[MAXRC + 1];

    for(row = 1; row <= M->mu; ++row) num[row] = 0;

    for(x = 1; x <= M->tu; ++x) ++num[M->data[x].i]; // 每一行非零元个数

    M->rpos[1] = 1;

    for(row = 2; row<=M->mu; ++row) M->rpos[row] = M->rpos[row-1] + num[row-1]; // 各行首个非零元位置

    return 1;

    }

    (2)稀疏矩阵加减法

    加减法基本思路一致,这里以加法为例。找到M和N矩阵各行非零元素的起始和终末位置之后开始遍历,对列号相等和不等两种情况分别处理,并处理相加结果等于0的情况。

    int AddSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix *Q){

    int arow;

    int p,q,s = 1;

    int tp,tq;

    if(M.mu != N.mu || M.nu != N.nu) return 0;

    Q->mu = M.mu; Q->nu = M.nu;

    for(arow = 1; arow <= M.mu; ++arow){

    Q->rpos[arow] = Q->tu + 1;

    p = M.rpos[arow]; q = N.rpos[arow];

    if(arow < M.mu){

    tp = M.rpos[arow + 1];

    tq = N.rpos[arow + 1];

    }

    else{

    tp = M.tu + 1;

    tq = N.tu + 1;

    }

    while(p < tp && q < tq){

    if(M.data[p].j != N.data[q].j){ // 列号不等

    if(M.data[p].j < N.data[q].j){

    Q->data[s].i = arow;

    Q->data[s].j = M.data[p].j;

    Q->data[s].e = M.data[p].e;

    s++; p++; Q->tu++;

    }else{

    Q->data[s].i = arow;

    Q->data[s].j = N.data[q].j;

    Q->data[s].e = N.data[q].e;

    s++; q++; Q->tu++;

    }

    }else{ // 列号相等

    if(M.data[p].e + N.data[q].e != 0){ // 结果非零

    Q->data[s].i = arow;

    Q->data[s].j = M.data[p].j;

    Q->data[s].e = M.data[p].e + N.data[q].e;

    s++; q++; p++; Q->tu++;

    }else{q++; p++;}

    }

    }

    while(p < tp){

    Q->data[s].i = arow;

    Q->data[s].j = M.data[p].j;

    Q->data[s].e = M.data[p].e;

    p++; s++; Q->tu++;

    }

    while(q < tq){

    Q->data[s].i = arow;

    Q->data[s].j = N.data[q].j;

    Q->data[s].e = N.data[q].e;

    q++; s++; Q->tu++;

    }

    }

    return 1;

    }

    (3)稀疏矩阵乘法

    对于M中每个元素M.data[p]找到N中所有满足条件M.data[p].j=N.data[q].i的元素N.data[q],求得M.data[p].e * N.data[q].e,对Q中元素设计累计和变量,初值为零,扫描数组M,求得相应元素乘积累加到适当的求累计和变量上。Q中元素行号与M中元素行号一致,又M中元素以M的行序为主序,因此对Q进行逐行处理,先求得累计和的中间结果(Q的一行),再压缩储存到Q.data中去。

    int MultSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix *Q){

    // 求矩阵乘积Q=M×N,采用行逻辑链接储存表示

    int arow,brow;

    int p,q,t,tp;

    int ccol;

    int ctemp[MAXRC + 1];

    if(M.nu != N.mu) return 0;

    Q->mu = M.mu; Q->nu = N.nu; Q->tu = 0; // Q初始化

    if(M.tu * N.tu != 0){ // Q是非零矩阵

    for(arow = 1; arow <= M.mu; ++arow){ // 处理M的每一行

    for(int i = 1; i <= N.nu; i++) ctemp[i] = 0; // 当前行各元素累加器清零

    Q->rpos[arow] = Q->tu + 1;

    if(arow < M.mu) tp = M.rpos[arow + 1];

    else{tp = M.tu + 1;}

    for(p = M.rpos[arow]; p

    brow = M.data[p].j; // 找到对应元所在N中的行号

    if(brow < N.mu) t = N.rpos[brow + 1];

    else{t = N.tu + 1;}

    for(q = N.rpos[brow]; q

    ccol = N.data[q].j; // 乘积元素在Q中的列号

    ctemp[ccol] += M.data[p].e * N.data[q].e;

    }// for q

    }// 求得Q中第crow(=arow)行的非零元

    for(ccol = 1; ccol <= Q->nu; ++ccol){ //压缩储存改行非零元

    if(ctemp[ccol]){

    if(++Q->tu > MAXSIZE) return 0;

    Q->data[Q->tu].i = arow;

    Q->data[Q->tu].j = ccol;

    Q->data[Q->tu].e = ctemp[ccol];

    }// if

    } // for ccol

    }// for arow

    }// if

    return 1;

    }// MultSMatrix

    (4)稀疏矩阵输出

    通过双重循环,打印稀疏矩阵中非零元和零元素

    int PrintSMatrix(RLSMatrix M){

    int row,col,t = 1;

    for(row = 1; row <= M.mu; row++){

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

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

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

    t++;

    }else{

    printf("0\t");

    }

    }

    printf("\n");

    }

    return 1;

    }

    2.2十字链表

    (1)稀疏矩阵创建

    读入矩阵行数、列数和非零元个数,同时提示输入各个非零元位置和数值,对于输入的非零元判断是否合法,生成结点并完成在行链表和列链表中的插入。

    int CreateSMatrix_OL(CrossList *M){

    if(M) free(M);

    int c;

    int m,n,t;

    int i,j,k,e;

    OLink p,q;

    do{

    printf("输入矩阵行数,列数和非零元数目,用空格隔开\n");

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

    if(m < 0 || n < 0 || t < 0 || t > m*n){

    printf("参数错误 \n");

    }

    }while(m < 0 || n < 0 || t < 0 || t > m*n);

    M->mu = m; M->nu = n; M->tu = t;

    if(!(M->rhead = (OLink*)malloc((m+1)*sizeof(OLink)))) exit(-2);

    if(!(M->chead = (OLink*)malloc((n+1)*sizeof(OLink)))) exit(-2);

    for(c = 1; c <= M->mu; c++) M->rhead[c]=NULL; // 初始化行列头指针向量

    for(c = 1; c <= M->nu; c++) M->chead[c]=NULL;

    for(k = 1; k <= t; k++){ // 按任意顺序输入非零元

    do{

    printf("输入第%d个非零元的行号 列号 值, 用空格隔开\n",k);

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

    if(i <= 0 || j <= 0 || i > m || j > n|| e==0){

    printf("参数错误\n");

    }

    }while(i <= 0 || j <= 0 || i > m || j > n|| e==0);

    if(!(p = (OLNode*)malloc(sizeof(OLNode)))) exit(-2);

    p->i = i; p->j = j; p ->e = e; // 生成结点

    if(M->rhead[i] == NULL || M->rhead[i]->j > j){

    p->right = M->rhead[i];

    M->rhead[i] = p;

    }else{ // 寻找行表中的插入位置

    for(q = M->rhead[i]; (q->right) && (q->right->j < j); q = q->right);

    p->right = q->right;

    q->right = p;

    } // 完成行插入

    if(M->chead[j] == NULL || M->chead[j]->i > i){ // 寻找列表中的插入位置

    p->down = M->chead[j];

    M->chead[j] = p;

    }else{

    for(q = M->chead[j]; (q->down) && (q->down->i < i); q = q->down);

    p->down = q->down;

    q->down = p;

    } // 完成列插入

    }

    return 1;

    }

    (2)稀疏矩阵加减法

    加减法基本思路一致,这里以加法为例。

    非空指针pa和pb分别指向矩阵A,B中行值相同的两个结点,pa==NULL表明矩阵A在改行没有非零元,分为以下四种情况:

    若pa==NULL或pa->j>pb->i,则需要在A矩阵的链表中插入一个值为bij的结点,此时,需要改变同一行中前一结点的right域值,以及同一列中前一结点的down域值。

    若pa->jj,则将pa指针向右推进一步

    若pa->j==pb->j,且pa->e+pb->e!=0,则只要将aij+bij的值送到pa所指结点的e域即可,其他所有域的值都不变

    若pa->j==pb->j,且pa->e+pb->e==0,则需要在A矩阵链表中删除pa所指结点,此时需要改变同一行中前一结点的right域值以及同一列前一结点的down阈值。

    为了便于插入和删除节点,还需要设置一些辅助指针。其一是在A的行链表上设pre指针,指示pa所指结点的前驱结点;其二是在A的每一列的链表上设一个指针hl[j],其初值和列链表的头指针相同,即hl[j]=chead[j]

    int AddSMatrix_OL(CrossList *A, CrossList *B){

    OLink pa, pb, pre, p, hl[MAXRC + 1];

    int i, j;

    if(A->mu != B->mu || A->nu != B->nu) return 0;

    for(j = 1; j <= A->nu; j++) hl[j] = A->chead[j];

    for(i = 1; i <= A->mu; i++){

    pa = A->rhead[i]; pb = B->rhead[i]; pre = NULL;

    while(pb){

    if(!(p = (OLNode*)malloc(sizeof(OLNode)))) exit(-2);

    p->i = pb->i; p->j = pb->j; p->e = pb->e;

    if(pa == NULL || pa->j > pb->j){ // 在A中插入pb所指结点的复制结点p

    if(pre == NULL) A->rhead[p->i] = p;

    else{pre->right = p; }

    p->right = pa;

    pre = p;

    if(A->chead[p->j] == NULL || A->chead[p->j]->i > p->i){

    p->down = A->chead[p->j];

    A->chead[p->j] = p;

    }else{ // 在hl[p->j]中找到新结点的前驱,插入结点

    p->down = hl[p->j]->down;

    hl[p->j]->down = p;

    }

    hl[p->j] = p;

    pb = pb->right;

    A->tu++;

    }else if(pa && pa->j < pb->j){ // pa指向本行下一个非零结点

    pre = pa;

    pa = pa->right;

    }else if(pa->j == pb->j){ // 加和

    pa->e += pb->e;

    if(pa->e == 0){ // 加和为0,删除结点,修改行表和列表相应指针

    if(pre == NULL) A->rhead[pa->i] = pa->right;

    else{pre->right = pa->right; }

    p = pa; pa = pa->right;

    if(A->chead[p->j] == p) A->chead[p->j] = hl[p->j] = p->down;

    else{hl[p->j]->down = p->down; }

    free(p);

    pb = pb->right;

    A->tu--;

    }else{pre = pa; pa = pa->right; pb = pb->right; }

    }

    }

    }

    return 1;

    }

    (3)稀疏矩阵乘法

    对于C中i行j列的元素,分别使p指向A中i行链表头指针,q指向B中j列链表头指针,累加和e置为零。p,q不为空时,

    当p->j > q->i,q指针下移

    当p->j < q->i,p指针右移

    当p->j == q->i,对乘积累计求和,并移动指针

    累加器e不为0时,则在矩阵C行列链表中插入节点p1,设置cpre和rpre分别指示行列链表中p1的前驱结点。

    int MultSMatrix_OL(CrossList A, CrossList B, CrossList *C){

    int i, j, e;

    OLink p, q, p1, rpre, cpre;

    if(A.nu != B.mu) return 0;

    C->mu = A.mu; C->nu = B.nu; C->tu = 0; // 初始化矩阵C

    if(!(C->rhead = (OLink*)malloc((C->mu+1)*sizeof(OLink)))) exit(-2);

    if(!(C->chead = (OLink*)malloc((C->nu+1)*sizeof(OLink)))) exit(-2);

    for(i = 1; i <= C->mu; i++) C->rhead[i] = NULL;

    for(j = 1; j <= C->nu; j++) C->chead[j] = NULL;

    for(i = 1; i <= C->mu; i++){

    for(j = 1; j <= C->nu; j++){

    p = A.rhead[i]; q = B.chead[j]; e = 0; // p,q分别指向A中该行链表头指针,B中该列链表头指针

    while(p && q){

    if(p->j > q->i){

    q = q->down;

    }else if(p->j < q->i){

    p = p->right;

    }else{

    e += p->e * q->e; // 乘积累加

    q = q->down;

    p = p->right;

    }

    }

    if(e){ // 累加不为0

    C->tu++;

    if(!(p1 = (OLNode*)malloc(sizeof(OLNode)))) exit(-2);

    p1->i = i; p1->j = j; p1->e = e;

    p1->right = NULL; p1->down = NULL;

    // 行插入

    if(C->rhead[i] == NULL) {C->rhead[i] = p1; rpre = p1;}

    else{rpre->right = p1; rpre = p1; }

    // 列插入

    if(C->chead[j] == NULL) {C->chead[j] = p1; cpre = p1;}

    else{cpre->down = p1; cpre = p1; }

    }

    }

    }

    return 1;

    }

    (4)稀疏矩阵输出

    通过双重循环,打印稀疏矩阵中非零元和零元素

    int PrintSMatrix_OL(CrossList M){

    OLink p;

    int row,col;

    for(row = 1; row <= M.mu; row++){

    if(M.rhead[row]){

    p = M.rhead[row];

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

    if(p->i == row && p->j == col && p != NULL){

    printf("%d\t",p->e);

    if(p->right) p = p->right;

    }else{printf("0\t");}

    }

    }else{for(col = 1; col <= M.nu; col++) printf("0\t");}

    printf("\n");

    }

    return 1;

    }

    4.主程序

    通过读入操作序号来进行相应操作,在满足操作对应条件下进行相应操作,并打印结果,两种储存方式下主程序结构基本一致,只是运算时调用函数不同。

    int main(){

    int num;

    CrossList M, N, Q;

    do{

    printf("操作:1.矩阵相加 2.矩阵相减 3.矩阵相乘 4.退出\n");

    scanf("%d",&num);

    if(num == 1 || num == 2 || num == 3){

    printf("请输入矩阵1\n");

    CreateSMatrix_OL(&M);

    printf("请输入矩阵2\n");

    CreateSMatrix_OL(&N);

    printf("两矩阵为:\n");

    PrintSMatrix_OL(M);

    printf("\n");

    PrintSMatrix_OL(N);

    switch(num){

    case 1:

    {

    if(AddSMatrix_OL(&M, &N)){

    printf("结果:\n");

    PrintSMatrix_OL(M);

    }

    else {printf("参数错误\n");}

    break;

    }

    case 2:

    {

    if(SubSMatrix_OL(&M, &N)){

    printf("结果:\n");

    PrintSMatrix_OL(M);

    }

    else {printf("参数错误\n");}

    break;

    }

    case 3:

    {

    if(MultSMatrix_OL(M,N,&Q)){

    printf("结果:\n");

    PrintSMatrix_OL(Q);

    }

    else {printf("参数错误\n");}

    break;

    }

    default: break;

    }

    }

    }while(num == 1 || num == 2 || num == 3);

    return 1;

    }

    5.程序的层次结构

    b04c32d1c27b?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

    层次结构

    四、用户手册

    本程序的运行环境为DOS操作系统,执行文件为:sparsematrix.exe和crossmatrix.exe 分别对应行逻辑链接顺序表和十字链表实现的稀疏矩阵计算器

    进入程序按提示操作,输入要进行操作对应的序号

    根据操作提示输入两矩阵的行数、列数和非零元个数,并输入非零元的行号,列号以及值

    结果打印

    根据操作提示退出程序

    五、测试结果

    \left[ \begin{matrix} 10&0& 0 \\ 0&0&9 \\ -1&0&0 \\ \end{matrix}\right] + \left[ \begin{matrix} 0&0& 0 \\ 0&0&-1 \\ 1&0&-3 \\ \end{matrix}\right]= \left[ \begin{matrix} 10&0& 0 \\ 0&0&8 \\ 0&0&-3 \\ \end{matrix}\right]

    \left[ \begin{matrix} 10&9 \\ 0&9 \\ -1&0 \\ \end{matrix}\right] - \left[ \begin{matrix} 0&0 \\ 0&-1 \\ 1&-3 \\ \end{matrix}\right]= \left[ \begin{matrix} 10&0 \\ 0&10 \\ -2&-3 \\ \end{matrix}\right]

    \left[ \begin{matrix} 4&-3&0&0&1 \\ 0&0&0&8&0 \\ 0&0&1&0&0 \\ 0&0&0&0&0 \end{matrix}\right] \times \left[ \begin{matrix} 3&0&0 \\ 4&2&0 \\ 0&1&0 \\ 1&0&0 \\ 0&0&0 \end{matrix}\right] = \left[ \begin{matrix} 0&-6&0 \\ 8&0&0 \\ 0&1&0 \\ 0&0&0 \end{matrix}\right]

    b04c32d1c27b?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

    测试结果1

    b04c32d1c27b?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

    测试结果2

    b04c32d1c27b?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

    测试结果3

    六、源代码

    sparsematrix.c

    #include

    #include

    #define MAXSIZE 400

    #define MAXRC 20

    typedef struct{

    int i,j;

    int e;

    }Triple;

    typedef struct{

    Triple data[MAXSIZE+1];

    int rpos[MAXRC+1];

    int mu,nu,tu; // 行,列,非零元个数

    }RLSMatrix;

    int CreateSMatrix(RLSMatrix *M){

    if(M) free(M);

    int m,n,t;

    do{

    printf("输入矩阵行数,列数和非零元数目,用空格隔开\n");

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

    if(m < 0 || n < 0 || t < 0 || t > m*n){

    printf("参数错误 \n");

    }

    }while(m < 0 || n < 0 || t < 0 || t > m*n);

    M->mu = m; M->nu = n; M->tu = t;

    printf("请按行优先输入三元组\n");

    int i,j,e,k;

    int p,q;

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

    do{

    printf("输入第%d个非零元的行号 列号 值, 用空格隔开\n",k);

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

    if(i <= 0 || j <= 0 || i > m || j > n|| e==0){

    printf("参数错误\n");

    }

    }while(i <= 0 || j <= 0 || i > m || j > n|| e==0);

    for(p = 1; p <= k-1 && (i > M->data[p].i || (i == M->data[p].i && j > M->data[p].j)); p++); //找到此三元组插入的位置

    for(q = k-1;q >= p; q--) M->data[q+1] = M->data[q]; //行序比它大的三元组依次向后移动

    M->data[p].i = i;

    M->data[p].j = j;

    M->data[p].e = e;

    }

    int row,x;

    int num[MAXRC + 1];

    for(row = 1; row <= M->mu; ++row) num[row] = 0;

    for(x = 1; x <= M->tu; ++x) ++num[M->data[x].i];

    M->rpos[1] = 1;

    for(row = 2; row<=M->mu; ++row) M->rpos[row] = M->rpos[row-1] + num[row-1];

    return 1;

    }

    int PrintSMatrix(RLSMatrix M){

    int row,col,t = 1;

    for(row = 1; row <= M.mu; row++){

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

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

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

    t++;

    }else{

    printf("0\t");

    }

    }

    printf("\n");

    }

    return 1;

    }

    int AddSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix *Q){

    int arow;

    int p,q,s = 1;

    int tp,tq;

    if(M.mu != N.mu || M.nu != N.nu) return 0;

    Q->mu = M.mu; Q->nu = M.nu;

    for(arow = 1; arow <= M.mu; ++arow){

    Q->rpos[arow] = Q->tu + 1;

    p = M.rpos[arow]; q = N.rpos[arow];

    if(arow < M.mu){

    tp = M.rpos[arow + 1];

    tq = N.rpos[arow + 1];

    }

    else{

    tp = M.tu + 1;

    tq = N.tu + 1;

    }

    while(p < tp && q < tq){

    if(M.data[p].j != N.data[q].j){ // 列号不等

    if(M.data[p].j < N.data[q].j){

    Q->data[s].i = arow;

    Q->data[s].j = M.data[p].j;

    Q->data[s].e = M.data[p].e;

    s++; p++; Q->tu++;

    }else{

    Q->data[s].i = arow;

    Q->data[s].j = N.data[q].j;

    Q->data[s].e = N.data[q].e;

    s++; q++; Q->tu++;

    }

    }else{ // 列号相等

    if(M.data[p].e + N.data[q].e != 0){ // 结果非零

    Q->data[s].i = arow;

    Q->data[s].j = M.data[p].j;

    Q->data[s].e = M.data[p].e + N.data[q].e;

    s++; q++; p++; Q->tu++;

    }else{q++; p++;}

    }

    }

    while(p < tp){

    Q->data[s].i = arow;

    Q->data[s].j = M.data[p].j;

    Q->data[s].e = M.data[p].e;

    p++; s++; Q->tu++;

    }

    while(q < tq){

    Q->data[s].i = arow;

    Q->data[s].j = N.data[q].j;

    Q->data[s].e = N.data[q].e;

    q++; s++; Q->tu++;

    }

    }

    return 1;

    }

    int SubSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix *Q){

    int arow;

    int p,q,s = 1;

    int tp,tq;

    if(M.mu != N.mu || M.nu != N.nu) return 0;

    Q->mu = M.mu; Q->nu = M.nu;

    for(arow = 1; arow <= M.mu; ++arow){

    Q->rpos[arow] = Q->tu + 1;

    p = M.rpos[arow]; q = N.rpos[arow];

    if(arow < M.mu){

    tp = M.rpos[arow + 1];

    tq = N.rpos[arow + 1];

    }

    else{

    tp = M.tu + 1;

    tq = N.tu + 1;

    }

    while(p < tp && q < tq){

    if(M.data[p].j != N.data[q].j){ // 列号不等

    if(M.data[p].j < N.data[q].j){

    Q->data[s].i = arow;

    Q->data[s].j = M.data[p].j;

    Q->data[s].e = M.data[p].e;

    s++; p++; Q->tu++;

    }else{

    Q->data[s].i = arow;

    Q->data[s].j = N.data[q].j;

    Q->data[s].e = - N.data[q].e;

    s++; q++; Q->tu++;

    }

    }else{ // 列号相等

    if(M.data[p].e - N.data[q].e != 0){

    Q->data[s].i = arow;

    Q->data[s].j = M.data[p].j;

    Q->data[s].e = M.data[p].e - N.data[q].e;

    s++; q++; p++; Q->tu++;

    }else{q++; p++;}

    }

    }

    while(p < tp){

    Q->data[s].i = arow;

    Q->data[s].j = M.data[p].j;

    Q->data[s].e = M.data[p].e;

    p++; s++; Q->tu++;

    }

    while(q < tq){

    Q->data[s].i = arow;

    Q->data[s].j = N.data[q].j;

    Q->data[s].e = - N.data[q].e;

    q++; s++; Q->tu++;

    }

    }

    return 1;

    }

    int MultSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix *Q){

    // 求矩阵乘积Q=M×N,采用行逻辑链接储存表示

    int arow,brow;

    int p,q,t,tp;

    int ccol;

    int ctemp[MAXRC + 1];

    if(M.nu != N.mu) return 0;

    Q->mu = M.mu; Q->nu = N.nu; Q->tu = 0; // Q初始化

    if(M.tu * N.tu != 0){ // Q是非零矩阵

    for(arow = 1; arow <= M.mu; ++arow){ // 处理M的每一行

    for(int i = 1; i <= N.nu; i++) ctemp[i] = 0; // 当前行各元素累加器清零

    Q->rpos[arow] = Q->tu + 1;

    if(arow < M.mu) tp = M.rpos[arow + 1];

    else{tp = M.tu + 1;}

    for(p = M.rpos[arow]; p

    brow = M.data[p].j; // 找到对应元所在N中的行号

    if(brow < N.mu) t = N.rpos[brow + 1];

    else{t = N.tu + 1;}

    for(q = N.rpos[brow]; q

    ccol = N.data[q].j; // 乘积元素在Q中的列号

    ctemp[ccol] += M.data[p].e * N.data[q].e;

    }// for q

    }// 求得Q中第crow(=arow)行的非零元

    for(ccol = 1; ccol <= Q->nu; ++ccol){ //压缩储存改行非零元

    if(ctemp[ccol]){

    if(++Q->tu > MAXSIZE) return 0;

    Q->data[Q->tu].i = arow;

    Q->data[Q->tu].j = ccol;

    Q->data[Q->tu].e = ctemp[ccol];

    }// if

    } // for ccol

    }// for arow

    }// if

    return 1;

    }// MultSMatrix

    int main(){

    int num;

    RLSMatrix M, N, Q;

    do{

    printf("操作:1.矩阵相加 2.矩阵相减 3.矩阵相乘 4.退出\n");

    scanf("%d",&num);

    if(num == 1 || num == 2 || num == 3){

    printf("请输入矩阵1\n");

    CreateSMatrix(&M);

    printf("请输入矩阵2\n");

    CreateSMatrix(&N);

    printf("两矩阵为:\n");

    PrintSMatrix(M);

    printf("\n");

    PrintSMatrix(N);

    switch(num){

    case 1:

    {

    if(AddSMatrix(M,N,&Q)){

    printf("结果:\n");

    PrintSMatrix(Q);

    }

    else {printf("参数错误\n");}

    break;

    }

    case 2:

    {

    if(SubSMatrix(M,N,&Q)){

    printf("结果:\n");

    PrintSMatrix(Q);

    }

    else {printf("参数错误\n");}

    break;

    }

    case 3:

    {

    if(MultSMatrix(M,N,&Q)){

    printf("结果:\n");

    PrintSMatrix(Q);

    }

    else {printf("参数错误\n");}

    break;

    }

    default: break;

    }

    }

    }while(num == 1 || num == 2 || num == 3);

    return 1;

    }

    crosmatrix.c

    #include

    #include

    #define MAXSIZE 400

    #define MAXRC 20

    typedef struct OLNode{

    int i,j;

    int e;

    struct OLNode *right, *down;

    }OLNode, *OLink;

    typedef struct {

    OLink *rhead, *chead;

    int mu, nu, tu;

    }CrossList;

    int CreateSMatrix_OL(CrossList *M){

    if(M) free(M);

    int c;

    int m,n,t;

    int i,j,k,e;

    OLink p,q;

    do{

    printf("输入矩阵行数,列数和非零元数目,用空格隔开\n");

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

    if(m < 0 || n < 0 || t < 0 || t > m*n){

    printf("参数错误 \n");

    }

    }while(m < 0 || n < 0 || t < 0 || t > m*n);

    M->mu = m; M->nu = n; M->tu = t;

    if(!(M->rhead = (OLink*)malloc((m+1)*sizeof(OLink)))) exit(-2);

    if(!(M->chead = (OLink*)malloc((n+1)*sizeof(OLink)))) exit(-2);

    for(c = 1; c <= M->mu; c++) M->rhead[c]=NULL;

    for(c = 1; c <= M->nu; c++) M->chead[c]=NULL;

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

    do{

    printf("输入第%d个非零元的行号 列号 值, 用空格隔开\n",k);

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

    if(i <= 0 || j <= 0 || i > m || j > n|| e==0){

    printf("参数错误\n");

    }

    }while(i <= 0 || j <= 0 || i > m || j > n|| e==0);

    if(!(p = (OLNode*)malloc(sizeof(OLNode)))) exit(-2);

    p->i = i; p->j = j; p ->e = e;

    if(M->rhead[i] == NULL || M->rhead[i]->j > j){

    p->right = M->rhead[i];

    M->rhead[i] = p;

    }else{

    for(q = M->rhead[i]; (q->right) && (q->right->j < j); q = q->right);

    p->right = q->right;

    q->right = p;

    }

    if(M->chead[j] == NULL || M->chead[j]->i > i){

    p->down = M->chead[j];

    M->chead[j] = p;

    }else{

    for(q = M->chead[j]; (q->down) && (q->down->i < i); q = q->down);

    p->down = q->down;

    q->down = p;

    }

    }

    return 1;

    }

    int PrintSMatrix_OL(CrossList M){

    OLink p;

    int row,col;

    for(row = 1; row <= M.mu; row++){

    if(M.rhead[row]){

    p = M.rhead[row];

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

    if(p->i == row && p->j == col && p != NULL){

    printf("%d\t",p->e);

    if(p->right) p = p->right;

    }else{printf("0\t");}

    }

    }else{for(col = 1; col <= M.nu; col++) printf("0\t");}

    printf("\n");

    }

    return 1;

    }

    int AddSMatrix_OL(CrossList *A, CrossList *B){

    OLink pa, pb, pre, p, hl[MAXRC + 1];

    int i, j;

    if(A->mu != B->mu || A->nu != B->nu) return 0;

    for(j = 1; j <= A->nu; j++) hl[j] = A->chead[j];

    for(i = 1; i <= A->mu; i++){

    pa = A->rhead[i]; pb = B->rhead[i]; pre = NULL;

    while(pb){

    if(!(p = (OLNode*)malloc(sizeof(OLNode)))) exit(-2);

    p->i = pb->i; p->j = pb->j; p->e = pb->e;

    if(pa == NULL || pa->j > pb->j){

    if(pre == NULL) A->rhead[p->i] = p;

    else{pre->right = p; }

    p->right = pa;

    pre = p;

    if(A->chead[p->j] == NULL || A->chead[p->j]->i > p->i){

    p->down = A->chead[p->j];

    A->chead[p->j] = p;

    }else{

    p->down = hl[p->j]->down;

    hl[p->j]->down = p;

    }

    hl[p->j] = p;

    pb = pb->right;

    A->tu++;

    }else if(pa && pa->j < pb->j){

    pre = pa;

    pa = pa->right;

    }else if(pa->j == pb->j){

    pa->e += pb->e;

    if(pa->e == 0){

    if(pre == NULL) A->rhead[pa->i] = pa->right;

    else{pre->right = pa->right; }

    p = pa; pa = pa->right;

    if(A->chead[p->j] == p) A->chead[p->j] = hl[p->j] = p->down;

    else{hl[p->j]->down = p->down; }

    free(p);

    pb = pb->right;

    A->tu--;

    }else{pre = pa; pa = pa->right; pb = pb->right; }

    }

    }

    }

    return 1;

    }

    int SubSMatrix_OL(CrossList *A, CrossList *B){

    OLink pa, pb, pre, p, hl[MAXRC + 1];

    int i, j;

    if(A->mu != B->mu || A->nu != B->nu) return 0;

    for(j = 1; j <= A->nu; j++) hl[j] = A->chead[j];

    for(i = 1; i <= A->mu; i++){

    pa = A->rhead[i]; pb = B->rhead[i]; pre = NULL;

    while(pb){

    if(!(p = (OLNode*)malloc(sizeof(OLNode)))) exit(-2);

    p->i = pb->i; p->j = pb->j; p->e = - pb->e;

    if(pa == NULL || pa->j > pb->j){

    if(pre == NULL) A->rhead[p->i] = p;

    else{pre->right = p; }

    p->right = pa;

    pre = p;

    if(A->chead[p->j] == NULL || A->chead[p->j]->i > p->i){

    p->down = A->chead[p->j];

    A->chead[p->j] = p;

    }else{

    p->down = hl[p->j]->down;

    hl[p->j]->down = p;

    }

    hl[p->j] = p;

    pb = pb->right;

    A->tu++;

    }else if(pa && pa->j < pb->j){

    pre = pa;

    pa = pa->right;

    }else if(pa->j == pb->j){

    pa->e -= pb->e;

    if(pa->e == 0){

    if(pre == NULL) A->rhead[pa->i] = pa->right;

    else{pre->right = pa->right; }

    p = pa; pa = pa->right;

    if(A->chead[p->j] == p) A->chead[p->j] = hl[p->j] = p->down;

    else{hl[p->j]->down = p->down; }

    free(p);

    pb = pb->right;

    A->tu--;

    }else{pre = pa; pa = pa->right; pb = pb->right; }

    }

    }

    }

    return 1;

    }

    int MultSMatrix_OL(CrossList A, CrossList B, CrossList *C){

    int i, j, e;

    OLink p, q, p1, rpre, cpre;

    if(A.nu != B.mu) return 0;

    C->mu = A.mu; C->nu = B.nu; C->tu = 0;

    if(!(C->rhead = (OLink*)malloc((C->mu+1)*sizeof(OLink)))) exit(-2);

    if(!(C->chead = (OLink*)malloc((C->nu+1)*sizeof(OLink)))) exit(-2);

    for(i = 1; i <= C->mu; i++) C->rhead[i] = NULL;

    for(j = 1; j <= C->nu; j++) C->chead[j] = NULL;

    for(i = 1; i <= C->mu; i++){

    for(j = 1; j <= C->nu; j++){

    p = A.rhead[i]; q = B.chead[j]; e = 0;

    while(p && q){

    if(p->j > q->i){

    q = q->down;

    }else if(p->j < q->i){

    p = p->right;

    }else{

    e += p->e * q->e;

    q = q->down;

    p = p->right;

    }

    }

    if(e){

    C->tu++;

    if(!(p1 = (OLNode*)malloc(sizeof(OLNode)))) exit(-2);

    p1->i = i; p1->j = j; p1->e = e;

    p1->right = NULL; p1->down = NULL;

    // 行插入

    if(C->rhead[i] == NULL) {C->rhead[i] = p1; rpre = p1;}

    else{rpre->right = p1; rpre = p1; }

    // 列插入

    if(C->chead[j] == NULL) {C->chead[j] = p1; cpre = p1;}

    else{cpre->down = p1; cpre = p1; }

    }

    }

    }

    return 1;

    }

    int main(){

    int num;

    CrossList M, N, Q;

    do{

    printf("操作:1.矩阵相加 2.矩阵相减 3.矩阵相乘 4.退出\n");

    scanf("%d",&num);

    if(num == 1 || num == 2 || num == 3){

    printf("请输入矩阵1\n");

    CreateSMatrix_OL(&M);

    printf("请输入矩阵2\n");

    CreateSMatrix_OL(&N);

    printf("两矩阵为:\n");

    PrintSMatrix_OL(M);

    printf("\n");

    PrintSMatrix_OL(N);

    switch(num){

    case 1:

    {

    if(AddSMatrix_OL(&M, &N)){

    printf("结果:\n");

    PrintSMatrix_OL(M);

    }

    else {printf("参数错误\n");}

    break;

    }

    case 2:

    {

    if(SubSMatrix_OL(&M, &N)){

    printf("结果:\n");

    PrintSMatrix_OL(M);

    }

    else {printf("参数错误\n");}

    break;

    }

    case 3:

    {

    if(MultSMatrix_OL(M,N,&Q)){

    printf("结果:\n");

    PrintSMatrix_OL(Q);

    }

    else {printf("参数错误\n");}

    break;

    }

    default: break;

    }

    }

    }while(num == 1 || num == 2 || num == 3);

    return 1;

    }

    展开全文
  • 稀疏矩阵是指那些多数元素为零的矩阵。利用“稀疏”特点进行存储和计算可以大大节省存储空间,提高计算效率。实现一个能进行稀疏矩阵基本运算的运算器
  • 清华大学版《数据结构》第三次试验代码,原创
  • 稀疏矩阵运算器 一、需求分析 1、稀疏矩阵是指那些多数元素为零的矩阵。利用“稀疏”特点进行存储和计算可以大大节省存储空间,提高计算效率。实现一个能进行稀疏矩阵基本运算的运算器。 2、以“带行逻辑链接信息...

    稀疏矩阵运算器

    一、需求分析

    1、稀疏矩阵是指那些多数元素为零的矩阵。利用“稀疏”特点进行存储和计算可以大大节省存储空间,提高计算效率。实现一个能进行稀疏矩阵基本运算的运算器。

    2、以“带行逻辑链接信息’的三元组顺序表示稀疏矩阵,实现两个矩阵相加,相减和相乘的运算,稀疏矩阵的输入形式采用三元组表示,而运算结果的矩阵则以通常的阵列形式列出。

    3、首先应输入矩阵的行数和列数,并判别给出的两个矩阵的行,列数对于所要求作的运算是否匹配,可设矩阵的行数和列数均不超过20。程序可以对三元组的输入顺序加以限制,例如,按行优先。在用三元组表示稀疏矩阵时,相加或相减所得结果矩阵应该另生成,乘积矩阵也可用二维数组存放。

    4、测试数据
    在这里插入图片描述

    二、详细代码

    #include<iostream>
    using namespace std;
    
    struct olnode {
        int i, j;    //行,列
        double e;    //元素值
        olnode *right, *down;
    };
    struct crosslist { //十字链表
        olnode **rhead, **chead;//r行指针,c列
        int mu, nu, tu; //行数 列数 非零元素数
    };
    int creatlist(crosslist &M) { //初始化十字链表
        int m, n, t;
        cout << "依次输入行,列,元素数目" << endl;
        while (!(cin >> m >> n >> t) || m <= 0 || n <= 0 || t<0||(m*n)<t||m>20||n>20) {
            cout << "error" << endl;
            cin.clear();
            cin.ignore();
        }
        M.mu = m;
        M.nu = n;
        M.tu = t;
        M.rhead = new olnode *[m + 1];
        M.chead = new olnode *[n + 1];
        for (int i = 0; i <= M.mu; i++)
            M.rhead[i] = NULL;
        for (int i = 0; i <= M.nu; i++)
            M.chead[i] = NULL;
        return t;
    }
    void creatlist1(crosslist &M, int a, int b) {//创建新矩阵
        M.mu = a;
        M.nu = b;
        M.tu = 0;
        M.rhead = new olnode *[a + 1];
        M.chead = new olnode *[b + 1];
        for (int i = 0; i <= M.mu; i++)
            M.rhead[i] = NULL;
        for (int i = 0; i <= M.nu; i++)
            M.chead[i] = NULL;
    }
    int check(crosslist M, int a, int b) {//检查是否重复插入元素
        olnode *p = M.rhead[a];
        olnode *q = M.chead[b];
        int l1 = 0, l2 = 0;
        if (M.rhead[a] == NULL || M.chead[b] == NULL) return 1;
        if (p->j == b) return 0;
        else{while (p->j != b && p->right != NULL) {
            p = p->right;
            if (p->j == b) l1 = 1;
        }
            if (l1 == 1) return 0;
            else return 1;
        }
    }
    int inlist(crosslist &M, int m, int n, double e) { //插入元素
        int f = 0;
        olnode *p = new olnode;
        p->i = m;
        p->j = n;
        p->e = e;
        olnode *q = new olnode;
    
        if (e == 0);
        else
            if (m > M.mu || n > M.nu||m<1||n<1)
                f = 1;
            else if (check(M, m, n) == 0) f = 1;//检查是否重复插入元素
            else {
                if (M.rhead[m] == NULL || M.rhead[m]->j > n)//判断要插入行是否有元素或要插入点前无其他元素
                {
                    p->right = M.rhead[m];
                    M.rhead[m] = p;
                }
                
                else {
                    for (q = M.rhead[m]; (q->right) && q->right->j < n; q = q->right);//插入行有元素且要插入点前有其他元素
                    p->right = q->right;
                    q->right = p;
                }
                //cout << "行插入完成" << endl;
                if (M.chead[n] == NULL || M.chead[n]->i > m)//判断要插入列是否有元素或要插入点前无其他元素
                {
                    p->down = M.chead[n];
                    M.chead[n] = p;
                }
                else {
                    for (q = M.chead[n]; (q->down) && q->down->i < m; q = q->down);//插入列有元素且要插入点前有其他元素
                    p->down = q->down;
                    q->down = p;
                }
            }
        return f;
        //cout << "列插入完成" << endl;
    }
    void addlist(crosslist a, crosslist b, crosslist &c) {//加法
        int m = a.mu, n = a.nu;
        double xa = 0, xb = 0;
        olnode *p = new olnode;
        olnode *q = new olnode;
        for (int i = 1; i <= m; i++) {
            p = a.rhead[i];
            q = b.rhead[i];
            {
                for (int j = 1; j <= n; j++) {
                    if (p && p->j == j) {
                        xa = p->e;
                        p = p->right;
                    }
                    else xa = 0;
                    if (q && q->j == j) {
                        xb = q->e;
                        q = q->right;
                    }
                    else xb = 0;
                    if ((xa + xb) != 0) inlist(c, i, j, xa + xb);
                }
            }
        }
    }
    void sublist(crosslist a, crosslist b, crosslist &c) {//减法
        int m = a.mu, n = a.nu;
        double xa = 0, xb = 0;
        olnode *p = new olnode;
        olnode *q = new olnode;
        for (int i = 1; i <= m; i++) {
            p = a.rhead[i];
            q = b.rhead[i];
            {
                for (int j = 1; j <= n; j++) {
                    if (p && p->j == j) {
                        xa = p->e;
                        p = p->right;
                    }
                    else xa = 0;
                    if (q && q->j == j) {
                        xb = -(q->e);
                        q = q->right;
                    }
                    else xb = 0;
                    if ((xa + xb) != 0) inlist(c, i, j, xa + xb);
                }
            }
        }
    }
    void mullist(crosslist a, crosslist b, crosslist &c) {//乘法
        double xa = 0, xb = 0, x = 0;
        olnode *p = new olnode;
        olnode *q = new olnode;
        for (int i = 1; i <= a.mu; i++) {
            p = a.rhead[i];
            for (int j = 1; j <= b.nu; j++) {
                q = b.chead[j];
                //cout << "第" << j << "列" << endl;
                x = 0;
                for (int k = 1; k <= a.nu; k++) {
                    if (p && p->j == k) {
                        xa = p->e;
                        p = p->right;
                    }
                    else xa = 0;
                    if (q && q->i == k) {
                        xb = q->e;
                        q = q->down;
                    }
                    else xb = 0;
                    x = x + xa * xb;
                    xa = 0; xb = 0;
                }
                if (x != 0) {
                    inlist(c, i, j, x);
                    x = 0;
                    
                }
                p = a.rhead[i];
            }
            
        }
    }
    void printflist(crosslist a) {
        int m = a.mu, n = a.nu;
        olnode *p = new olnode;
        //cout << "行循环开始" << endl;
        for (int i = 1; i <= m; i++) {
            p = a.rhead[i];
            {
                for (int j = 1; j <= n; j++) {
                    if (p && p->j == j) {
                        cout << " " << p->e << " ";
                        p = p->right;
                    }
                    else cout << " 0 ";
                }
            }
            cout << endl;
        }
    }
    
    int main() {
        
        int num1 = 0;
        int num2 = 0;
        int num3 = 0;
        int a, b;
        double e;
        crosslist list1, list2, list3;
        cout << " 1:加法\n 2:减法\n 3:乘法" << endl;
        while (1) {
            int cho;
            while (!(cin >> cho)) {
                cout << "error" << endl;
                cin.clear();
                cin.ignore();
            }
            if (cho == 1) {//加法
                num1 = creatlist(list1);
                num2 = creatlist(list2);
                if (list1.mu == list2.mu&&list1.nu == list2.nu) {
                    creatlist1(list3, list1.mu, list1.nu);
                    for (int i = 0; i < num1; i++) {
                        cout << "依次输入矩阵1的行,列,元素值" << endl;
                        while (!(cin >> a >> b >> e) || inlist(list1, a, b, e)) {
                            cout << "error" << endl;
                            cin.clear();
                            cin.ignore();
                        }
                        
                    }
                    for (int i = 0; i < num2; i++) {
                        cout << "依次输入矩阵2的行,列,元素值" << endl;
                        while (!(cin >> a >> b >> e) || inlist(list2, a, b, e)) {
                            cout << "error" << endl;
                            cin.clear();
                            cin.ignore();
                        }
                    }
    
                    addlist(list1, list2, list3);
                    printflist(list3);
                }
                else cout << "error" << endl;
            }
            else
                if (cho == 2) {//减法
                    num1 = creatlist(list1);
                    num2 = creatlist(list2);
                    if (list1.mu == list2.mu&&list1.nu == list2.nu) {
                        creatlist1(list3, list1.mu, list1.nu);
                        for (int i = 0; i < num1; i++) {
                            cout << "依次输入矩阵1的行,列,元素值" << endl;
                            while (!(cin >> a >> b >> e) || inlist(list1, a, b, e)) {
                                cout << "error" << endl;
                                cin.clear();
                                cin.ignore();
                            }
                            
                        }
                        for (int i = 0; i < num2; i++) {
                            cout << "依次输入矩阵2的行,列,元素值" << endl;
                            while (!(cin >> a >> b >> e) || inlist(list2, a, b, e)) {
                                cout << "error" << endl;
                                cin.clear();
                                cin.ignore();
                            }
                        }
    
                        sublist(list1, list2, list3);
                        printflist(list3);
                    }
                    else cout << "error" << endl;
                }
                else
                    if (cho == 3) {//乘法
                        num1 = creatlist(list1);
                        num2 = creatlist(list2);
                        if (list1.nu == list2.mu) {
                            creatlist1(list3, list1.mu, list2.nu);
                            for (int i = 0; i < num1; i++) {
                                cout << "依次输入矩阵1的行,列,元素值" << endl;
                                while (!(cin >> a >> b >> e) || inlist(list1, a, b, e)) {
                                    cout << "error" << endl;
                                    cin.clear();
                                    cin.ignore();
                                }
                                
                            }
                            for (int i = 0; i < num2; i++) {
                                cout << "依次输入矩阵2的行,列,元素值" << endl;
                                while (!(cin >> a >> b >> e) || inlist(list2, a, b, e)) {
                                    cout << "error" << endl;
                                    cin.clear();
                                    cin.ignore();
                                }
                            }
    
                            mullist(list1, list2, list3);
                            printflist(list3);
                        }
                        else cout << "error" << endl;
                    }
        }
    }
    
    

    三、测试结果
    加法👇在这里插入图片描述
    减法👇
    在这里插入图片描述
    乘法👇
    在这里插入图片描述

    展开全文
  • /*****************稀疏矩阵运算器 ****************/#include#include#define OK 1#define TRUE 1#define ERROR 0#define FALSE 0#define MAX_SIZE 100typedef struct{ //构造三元组int x;int y;int e;}Triad;...

    /*****************稀疏矩阵运算器 ****************/

    #include

    #include

    #define OK 1

    #define TRUE 1

    #define ERROR 0

    #define FALSE 0

    #define MAX_SIZE 100

    typedef struct{ //构造三元组

    int x;

    int y;

    int e;

    }Triad;

    typedef struct {

    int mrow,mcol,ms;

    Triad data[MAX_SIZE];

    }Rtriad;

    void Input(Rtriad &S){ //以三元组方式输入矩阵

    printf("请输入行,列(row col):");

    scanf("%d%d",&S.mrow,&S.mcol);

    printf("请以行序为主序,以三元组的方式输入矩阵元素,'-1 -1 -1'表示结束:\n");

    int x,y,z;

    scanf("%d%d%d",&x,&y,&z);

    S.ms=0;

    while(!(x==-1&&y==-1&&z==-1)){ //长度为S.ms+1,从0开始到S.ms

    S.data[S.ms].x=x;

    S.data[S.ms].y=y;

    S.data[S.ms].e=z;

    S.ms++;

    scanf("%d%d%d",&x,&y,&z);

    }

    S.ms--;

    }

    void Add(Rtriad S1,Rtriad S2,Rtriad &S3){ //矩阵相加

    if(S1.mcol!=S2.mcol||S1.mrow!=S2.mrow){

    printf("ERROR!!!\n");

    return ;

    }

    S3.mcol=S1.mcol ;

    S3.mrow=S1.mrow ;

    S3.ms=0;

    int row,col,s,x,y,z;

    for(row=1;row<=S3.mrow;row++){

    for(col=1;col<=S3.mcol;col++){

    z=0;

    for(s=0;s<=S1.ms;s++){

    if(S1.data[s].x==row&&S1.data[s].y==col){

    S3.data[S3.ms].x=row;

    S3.data[S3.ms].y=col;

    S3.data[S3.ms].e=S1.data[s].e;

    z++;

    }

    }

    for(s=0;s<=S2.ms;s++){

    if(S2.data[s].x==row&&S2.data[s].y==col){

    S3.data[S3.ms].x=row;

    S3.data[S3.ms].y=col;

    if(z==0)

    S3.data[S3.ms].e=S2.data[s].e;

    else

    S3.data[S3.ms].e+=S2.data[s].e;

    z++;

    }

    }

    if(z!=0)

    S3.ms++;

    }

    }

    int m=0;

    for(int t=0;t<=S3.ms;t++){

    if(S3.data[t].e==0){ //删除

    for(int i=t+1;i

    S3.data[i-1]=S3.data[i];

    }

    m++;

    }

    }

    S3.ms-=m;

    }

    void Printf(Rtriad S){ //打印矩阵

    int a[S.mrow][S.mcol];

    for(int i=0;i

    for(int j=0;j

    a[i][j]=0;

    for(int k=0;k<=S.ms;k++)

    a[S.data[k].x-1][S.data[k].y-1]=S.data[k].e;

    //printf("\n\n矩阵为:\n");

    for(int i=0;i

    for(int j=0;j

    printf("%-2d ",a[i][j]);

    printf("\n");

    }

    }

    void Sub(Rtriad S1,Rtriad S2,Rtriad &S3){ //矩阵相减

    for(int i=0;i<=S2.ms;i++)

    S2.data[i].e*=-1;

    Add(S1,S2,S3);

    for(int i=0;i<=S2.ms;i++)

    S2.data[i].e*=-1;

    }

    void Mult(Rtriad S1,Rtriad S2,Rtriad &S3){ //矩阵相乘

    if(S1.mcol!=S2.mrow){

    printf("ERROR!!!\n");

    return ;

    }

    S3.mrow=S1.mrow;

    S3.mcol=S2.mcol;

    S3.ms=0;

    int s1[S1.mrow][S1.mcol];

    int s2[S2.mrow][S2.mcol];

    int s3[S3.mrow][S3.mcol];

    for(int i=0;i

    for(int j=0;j

    s1[i][j]=0;

    for(int i=0;i

    for(int j=0;j

    s2[i][j]=0;

    for(int i=0;i

    for(int j=0;j

    s3[i][j]=0;

    for(int k=0;k<=S1.ms;k++)

    s1[S1.data[k].x-1][S1.data[k].y-1]=S1.data[k].e;

    for(int k=0;k<=S2.ms;k++)

    s2[S2.data[k].x-1][S2.data[k].y-1]=S2.data[k].e;

    for(int row=0;row

    for(int col=0;col

    for(int k=0;k

    s3[row][col]+=(s1[row][k]*s2[k][col]);

    if(s3[row][col]!=0){

    S3.data[S3.ms].x=row+1;

    S3.data[S3.ms].y=col+1;

    S3.data[S3.ms].e=s3[row][col];

    S3.ms++;

    }

    }

    }

    }

    void Tran(Rtriad &S1,Rtriad &S2){ //矩阵的快速转置

    S2.ms=S1.ms;

    S2.mcol=S1.mrow;

    S2.mrow=S1.mcol;

    int num[MAX_SIZE]; //每一列的元素个数 ,从1开始计数

    int pos[MAX_SIZE];

    for(int col=1;col<=S1.mcol;col++) //初始化num

    num[col]=0;

    for(int i=0;i<=S1.ms;i++) //给num赋值 ,num从1开始

    num[S1.data[i].y]++;

    pos[1]=1; //给pos赋值 ,pos从1开始

    for(int col=2;col<=S1.mcol;col++)

    pos[col]=pos[col-1]+num[col-1];

    for(int k=0;k<=S1.ms;k++){ //S1,S2都是从data[0]开始的

    int col=S1.data[k].y;

    int q=pos[col];

    S2.data[q-1].e=S1.data[k].e;

    S2.data[q-1].x=S1.data[k].y;

    S2.data[q-1].y=S1.data[k].x;

    pos[col]++;

    }

    }

    int main(){

    printf("/*****************稀疏矩阵运算器 ****************/\n\n");

    printf("功能选择:\n1.矩阵相加\n2.矩阵相减\n3.矩阵相乘\n4.矩阵转置\n");

    int n;

    printf("选择功能:");

    scanf("%d",&n);

    Rtriad S1,S2,S3;

    switch(n){

    case 1:

    printf("\n请输入矩阵1:\n");

    Input(S1);

    printf("\n请输入矩阵2:\n");

    Input(S2);

    Add(S1,S2,S3);

    printf("\n结果为:\n");

    Printf(S3);

    break;

    case 2:

    printf("\n请输入矩阵1:\n");

    Input(S1);

    printf("\n请输入矩阵2:\n");

    Input(S2);

    Sub(S1,S2,S3);

    printf("\n结果为:\n");

    Printf(S3);

    break;

    case 3:

    printf("\n请输入矩阵1:\n");

    Input(S1);

    printf("\n请输入矩阵2:\n");

    Input(S2);

    Mult(S1,S2,S3);

    printf("\n结果为:\n");

    Printf(S3);

    break;

    case 4:

    printf("\n请输入矩阵1:\n");

    Input(S1);

    Tran(S1,S2);

    printf("\n结果为:\n");

    Printf(S3);

    break;

    }

    return 0;

    }

    展开全文
  • 简单的运算器,可以满足加法减法和乘法,采用的三元组逻辑链接结构。
  • 是数据结构(严蔚敏版)课程设计,稀疏矩阵运算器的代码和报告
  • 稀疏矩阵运算器(c++)

    2009-06-22 21:09:47
    用c++语言编写的稀疏矩阵运算器(包括矩阵的加减乘法),并附课程设计报告.详细过程见原文.
  • 以“带行逻辑连接信息”的三元组顺序表表示稀疏矩阵,实现两矩阵相加,相减,相乘的运算稀疏矩阵的输入用三元组表示,而运算结果以列阵形式列出。
  • 稀疏矩阵运算器.rar

    2021-04-01 12:00:26
    实现任意两个稀疏矩阵的加、减和乘运算和任一稀疏矩阵的转置运算
  • 实现一个能进行稀疏矩阵基本运算的运算器。以“带行逻辑链接信息”的三元组顺序表表示稀疏矩阵,实现两个矩阵相加、相减和相乘的运算。稀疏矩阵的输入形式采用三元组表示,而运算结果的矩阵则以通常的阵列形式列出。...
  • (数据结构课程设计)稀疏矩阵运算器

    千次阅读 多人点赞 2017-05-24 22:53:48
    实现一个能进行稀疏矩阵基本运算的运算器。 具体功能有:(1)以“带行逻辑链接信息”的三元组顺序表示稀疏矩阵,实现两个稀疏矩阵相加、相减、相乘和求逆的运算。(2)稀疏矩阵的输入形式采用三元组表示,而运算...
    1.设计内容
    
      稀疏矩阵是指那些多数元素为零的矩阵。利用“稀疏”特点进行存储和计算可以大大节省存储空间,提高计算准备效率。实现一个能进行稀疏矩阵基本运算的运算器。
    具体功能有:
    (1)以“带行逻辑链接信息”的三元组顺序表示稀疏矩阵,实现两个稀疏矩阵相加、相减、相乘、求逆以及矩阵转置和求矩阵对应行列式值的功能。
    (2)稀疏矩阵的输入形式采用三元组表示,而运算结果的矩阵则以通常的阵列形式列出。
    2. 本设计所采用的数据结构
    稀疏矩阵采用带行逻辑链接信息的三元组顺序存储


    本设计最终代码实现如下(C语言):

    #include<stdio.h>
    #include<math.h>
    #include<stdlib.h>
    #include<conio.h>
    #include<malloc.h>
    #include<string.h>
    #define MAXSIZE 100          /*假设非零元个数的最大值为100*/
    #define MAXMU 25              /*稀疏矩阵最大行列值为25*/
    typedef struct
    {
    	int i,j;                 /*该非零元的行下标和列下标*/
    	int v;
    }Triple;
    typedef struct            /*稀疏矩阵是由三元组的顺序存储*/
    {   int rpos[MAXMU+1];	     /*各行第一个非零元素的位置表*/
    	Triple data[MAXSIZE+1];  /*非零元三元组顺序表,data[0]未使用*/
    	int mu,nu,tu;            /*矩阵的行数,列数和非零元个数*/
    }TSMatrix;
    
    void creat(TSMatrix *T) /*由用户输入创建稀疏矩阵*/
    {
    	int row,num,k;
    	do
    	{
    		system("cls");
    		system("color 4f");
    		printf("\n 请输入矩阵!\n");
    		printf("*********************************\n");
    		printf(" 请输入稀疏矩阵行数: ");
    		scanf("%d", &T->mu);
    		if (T->mu<0 || T->mu>MAXMU)
    			printf("\n 行数超出定义范围,请重新输入!\n");
    	} while (T->mu<0 || T->mu>MAXMU);
    	do
    	{
    		printf(" 请输入稀疏矩阵列数: ");
    		scanf("%d", &T->nu);
    		if (T->nu<0 || T->nu>MAXMU)
    			printf("\n 列数超出定义范围,请重新输入!\n");
    	} while (T->nu<0 || T->nu>MAXMU);
    	do
    	{
    		printf(" 请输入稀疏矩阵的非零元素个数: ");
    		scanf("%d", &T->tu);
    		if (T->tu>MAXSIZE || (T->tu>T->mu*T->nu))
    			printf("\n 非零元素个数超出定义范围,请重新输入!\n");
    	} while (T->tu>MAXSIZE || (T->tu>T->mu*T->nu));
    	printf("**********************************\n");
    	printf(" 请按行从小到大依次输入结点信息!\n");
    	for (k=1; k<=T->tu; k++)
    	{
    		do
    		{
    			printf(" 请按三元组存储输入第%d个非零元素的行数i:", k);
    			scanf("%d", &T->data[k].i);
    			if (!T->data[k].i || T->data[k].i>T->mu)
    				printf("\n 输入有误,请重新输入!\n");
    		} while ((!T->data[k].i || T->data[k].i>T->mu));
    		do
    		{
    			printf(" 请按三元组存储输入第%d个非零元素的列数j:", k);
    			scanf("%d", &T->data[k].j);
    			if (!T->data[k].j || T->data[k].j>T->nu)
    				printf("\n 输入有误,请重新输入!\n");
    		} while ((!T->data[k].j || T->data[k].j>T->nu));
    		do
    		{
    			printf(" 请按三元组存储输入第%d个非零元素的值v:", k);
    			scanf("%d", &T->data[k].v);
    			if (T->data[k].v==0)
    				printf("\n 输入有误,请重新输入!\n");
    		} while (T->data[k].v==0);
    		printf("***********************************\n");
    	}
    	for(row=1,num=1;row<=T->mu;row++)   /*行逻辑链接信息存储*/
    	{
    		T->rpos[row]=num;
    		while(T->data[num].i==row)
    			num++;
    	}
    	return;
    }
    
    void print(TSMatrix A)   /*输出稀疏矩阵*/
    {
    	int q,n,k,a=0;
        system("cls");
        system("color 4f");
        printf("\n\n经过稀疏矩阵运算器运算,所得结果为:\n");
        printf("***********************************\n");
        printf("***********************************\n");
    	for(n=1;n<=A.mu;n++)
    	{
    	 for(k=1;k<=A.nu;k++)
           {
    		 for(q=1;q<=A.tu;q++)
    			 if(A.data[q].i==n && A.data[q].j==k)
    			 {
    				 printf("\t%-3d",A.data[q].v);break;
    			 }
    		 if(q>A.tu)
    			 printf("\t%-3d",a);		 
    	   }
    	 printf("\n");
    	} 
    	printf("***********************************\n");
    	printf("***********************************\n");
     }
    
    void add(TSMatrix A,TSMatrix B)   /*加法运算*/
    {
    	system("color 4f");
    	int n,k;
    	if(A.mu!=B.mu || A.nu!=B.nu)
    	{ 
    		printf("\n          不满足矩阵相加条件!"); 
            printf("\n 需满足两矩阵的行数、列数均对应相等方可进行加法运算!!");
    	}
    	else  
    	{
    		for(n=1;n<=A.tu;n++)
    	         for(k=1;k<=B.tu;k++)   /*将矩阵A的非零元接至B中*/
    				 if(A.data[n].i==B.data[k].i && A.data[n].j==B.data[k].j)
    				 {
    					 A.data[n].v+=B.data[k].v;
    			         B.data[k].v=0;
    				 }
    		for(k=1;k<=B.tu;k++)
    			if(B.data[k].v!=0)
    			{
    				A.data[A.tu+1].i=B.data[k].i;
    				A.data[A.tu+1].j=B.data[k].j;
    				A.data[A.tu+1].v=B.data[k].v;
    				A.tu++;	
    			}
    		print(A);
         }
    }
    
    void sub(TSMatrix A,TSMatrix B)   /*减法运算*/
    {
    	system("color 4f");
    	int n,k;
        if(A.mu!=B.mu || A.nu!=B.nu)
    	{
    		printf("\n    不满足矩阵相减条件!"); 
    		printf("\n 需要满足两矩阵的行数、列数均对应相等方可进行减法运算!!");
    	}
    	else
    	{
    	    for(n=1;n<=A.tu;n++)
    	        for(k=1;k<=B.tu;k++)   /*将矩阵A的非零元接至B中*/
    				if(A.data[n].i==B.data[k].i && A.data[n].j==B.data[k].j)
    				{
    					A.data[n].v-=B.data[k].v;
    					B.data[k].v=0;
    				}
                for(k=1;k<=B.tu;k++)
    				if(B.data[k].v!=0)
    				{
    					A.data[A.tu+1].i=B.data[k].i;
    				    A.data[A.tu+1].j=B.data[k].j;
    				    A.data[A.tu+1].v=-B.data[k].v;
    				    A.tu++;
    				}
    		print(A);  
    	}
    }
    
    void mult(TSMatrix A,TSMatrix B,TSMatrix *c)   /*乘法运算*/
    {
    	system("color 4f");
    	int arow,tp,i,t;
    	int ccol,p,brow,q;
    	int ctemp[MAXMU+1];
    	if(A.nu!=B.mu)
    	{
    		printf(" 矩阵不满足相乘条件!");
    		return ;
    	}
    	c->mu=A.mu;
    	c->nu=B.nu;
    	c->tu=0;
    	if(A.tu==0||B.tu==0)
    	{
    		printf(" 结果矩阵为零!");
    		return ;
    	}
    	else
    	{
    		for(arow=1;arow<=A.mu;arow++)
    		{
    			for(i=0;i<MAXMU;i++)    /*存储器清零*/
    				ctemp[i]=0;
    			c->rpos[arow]=c->tu+1;
    			if(arow<A.mu)
    				tp=A.rpos[arow+1];
    			else
    				tp=A.tu+1;
    			for(p=A.rpos[arow];p<tp;p++)
    			{
    				brow=A.data[p].j;
    				if(brow<B.mu)
    					t=B.rpos[brow+1];
    				else
    					t=B.tu+1;
    				for(q=B.rpos[brow];q<t;q++)
    				{
    					ccol=B.data[q].j;
    					ctemp[ccol]+=A.data[p].v*B.data[q].v;
    				}
    			}
    			for(ccol=1;ccol<=c->nu;ccol++)
    				if(ctemp[ccol])
    				{
    					if(++(c->tu)>MAXSIZE)
    					{
    						printf("超出范围!");
    						return ;
    					}
    				    c->data[c->tu].v=ctemp[ccol];
    				    c->data[c->tu].i=arow;
    				    c->data[c->tu].j=ccol;
    				}
    		}
    	}
    	print(*c);
    }
    
    char menu()   /*计算器主界面(菜单)*/
    {
    	char n;
        system("color 4f"); 
    	system("title 稀疏矩阵运算器"); 
        system("cls");
    	system("mode con cols=70 lines=30");
        printf("\n");
        printf("\n            课程设计  ******班                      \n\n\n\n\n\n");
     
        printf("              ****************************************          \n");
        printf("              *                                      *          \n");
        printf("              *         稀 疏 矩 阵 运 算 器         *          \n");
        printf("              *                                      *          \n");
        printf("              *             实 现 运 算              *          \n");
        printf("              *                                      *          \n");
        printf("              *             1:矩阵相加               *          \n");
        printf("              *             2:矩阵相減               *          \n");
        printf("              *             3:矩阵相乘               *          \n");
        printf("              *             4:矩阵求逆               *          \n");
    	printf("              *             5:矩阵转置               *          \n");
        printf("              *             6:行列式值               *          \n");
    	printf("              *             7:选择退出               *          \n");
    	printf("              *                                      *          \n");
        printf("              ****************************************          \n");
        printf("                        请输入序号进行操作  :)                 \n");
        printf("                                 ");n=getchar();
    	 
        return n;
    }
    
    void zhuanzhi(TSMatrix A)   /*转置运算*/
    {
    	int p,q,m;
    	TSMatrix B;
    	B.mu=A.nu; /*将原矩阵的行列数及非零元个数赋给新矩阵*/
    	B.nu=A.mu;
    	B.tu=A.tu;
    	if(B.tu)
    	{
    		m=1;
    		for(p=1;p<=A.mu;p++)              /*将原非零元三元组的行列值交换后赋给新三元组,得到转置矩阵*/
    			for(q=1;q<=A.nu;q++)
    			{
    				B.data[m].i=A.data[m].j;
    				B.data[m].j=A.data[m].i;
    				B.data[m].v=A.data[m].v;
    				++m;
    			}
    	}
    	print(B);
    }
    
    int JsMatrix(int s[][MAXMU],int n) /*通过递归求矩阵对应行列式的值*/   
    {
    	int z,j,k,r,total=0;
    	int b[MAXMU][MAXMU];
    	if(n>2)
    	{
    		for(z=0;z<n;z++)
    			{for(j=0;j<n-1;j++)
    				for(k=0;k<n-1;k++)
    					if(k>=z) b[j][k]=s[j+1][k+1];
    					else b[j][k]=s[j+1][k];
    					if(z%2==0) r=s[0][z]*JsMatrix(b,n-1);
    					else r=(-1)*s[0][z]*JsMatrix(b,n-1);
    			total=total+r;
    			}
    	}
    	else if(n==2) total=s[0][0]*s[1][1]-s[0][1]*s[1][0];
    	return total;
    }
    
    void yuzishi(int s[][MAXMU],int b[][MAXMU],int n) /*求矩阵每个元素对应的余子式*/
    {
    	int z,j,k,m,l,g,a[MAXMU][MAXMU];
    	for(z=0;z<n;z++)
    	{
    		l=z;
    		for(j=0;j<n;j++)
    		{	
    			m=j;
    			for(k=0;k<n-1;k++)
    				for(g=0;g<n-1;g++)
    				{
    					if(g>=m&&k<l) a[k][g]=s[k][g+1];
    					else if(k>=l&&g<m)  a[k][g]=s[k+1][g];
    				    else if(k>=l&&g>=m) a[k][g]=s[k+1][g+1];
    				    else   a[k][g]=s[k][g];
    				}	
    			b[z][j]=JsMatrix(a,n-1);/*调用求行列式函数求出余子式*/
    		}
    	}
    }
    
    void qiuni(TSMatrix TM)   /*求逆运算*/
    {
    	system("color 4f");
    	int i,j,n,k;
    	n=TM.mu;
    	float temp;
    	int a[MAXMU][MAXMU];
    	int b[MAXMU][MAXMU];
    	float c[MAXMU][MAXMU];
    	for(i=0;i<n;i++)
    		for(j=0;j<n;j++)
    			a[i][j]=0;
    	for(i=1;i<=TM.tu;i++)
    		a[TM.data[i].i-1][TM.data[i].j-1]=TM.data[i].v;
    	k=JsMatrix(a,n); /*调用求行列式值的函数求出行列式的值*/
    	printf(" 矩阵的行列式的值为:|A|=%d\n",k);
    	if(k==0)
    		printf(" 行列式的值|A|=0,原矩阵无逆矩阵!");
    	else
    	{
    		yuzishi(a,b,n);
    
    		for(i=0;i<n;i++) /*由余子式得到代数余子式*/
    			for(j=0;j<n;j++)
    				if((i+j)%2!=0 && b[i][j]!=0) 
    					b[i][j]=-b[i][j];
    
    		for(i=0;i<n;i++) /*将代数余子式矩阵转置得到伴随矩阵*/
    			for(j=i+1;j<n;j++)
    			{
    				temp=b[i][j];
    				b[i][j]=b[j][i];
    				b[j][i]=temp;
    			}
    
    		printf(" 伴随矩阵A*为:\n");
    		for(i=0;i<n;i++) /*输出伴随矩阵*/
    		{
    			printf("\n");
    			for(j=0;j<n;j++)
    				printf("%6d",b[i][j]);
    			printf("\n");
    		}
    		for(i=0;i<n;i++)/*伴随矩阵除以行列式的值得到逆矩阵*/
    			for(j=0;j<n;j++)
    				c[i][j]=(float)b[i][j]/k;
    		printf(" 逆矩阵(A*)/|A|为:\n"); 
    		for(i=0;i<n;i++)/*输出逆矩阵*/
    		{
    			printf("\n");
    				for(j=0;j<n;j++)
    					printf("%1.1f\t",c[i][j]);		    
    			printf("\n");
    		}
    	}
    }
    void hlsz(TSMatrix TM)   /*求逆运算*/
    {
    	system("color 4f");
    	int i,j,n,k;
    	n=TM.mu;
    	float temp;
    	int a[MAXMU][MAXMU];
    	int b[MAXMU][MAXMU];
    	float c[MAXMU][MAXMU];
    	for(i=0;i<n;i++)
    		for(j=0;j<n;j++)
    			a[i][j]=0;
    	for(i=1;i<=TM.tu;i++)
    		a[TM.data[i].i-1][TM.data[i].j-1]=TM.data[i].v;
    	k=JsMatrix(a,n); /*调用求行列式值的函数求出行列式的值*/
    	printf("该稀疏矩阵对应行列式的值为%d",k);
    }
    void main() /*功能主函数*/
    { 
    	TSMatrix A,B,C;
    
    	 for(;;)
    		 switch(menu())
    	 {case '1':creat(&A);
                   creat(&B);
    			   add(A,B);
    			   getch();
    			   break;
          case '2':creat(&A);
                   creat(&B);
    			   sub(A,B);
    			   getch();
    			   break;
          case '3':creat(&A);
                   creat(&B);
    			   mult(A,B,&C);
    			   getch();
    			   break;
    	  case '4':creat(&A);
    		       qiuni(A);
    			   getch();
    			   break;
    	  case '5':creat(&A);
    		       zhuanzhi(A);
    			   getch();
    			   break;
    	  case '6':creat(&A);
    		       hlsz(A);
    			   getch();
    			   break;
          case '7':system("cls");
    			  system("color f2");
    			  printf("计算器已关闭,按任意键退出 :)\n");
    			  exit(0);
    	 }
    }
    



    展开全文
  • 实现一个能进行稀疏矩阵基本运算的运算器 基本要求 以“带行逻辑连接信息”的三元组顺序表表示系数矩阵,实现两个矩阵相加、相减和想乘的运算。稀疏矩阵的输入形式采用三元组表示,而运算结果的矩阵以通常阵列形式列...
  • 稀疏矩阵运算器.pdf

    2021-10-01 21:57:51
    稀疏矩阵运算器.pdf
  • 10稀疏矩阵运算器.doc

    2021-12-05 22:14:55
    10稀疏矩阵运算器.doc
  • 实现一个能进行稀硫矩阵基本运算的运算器。 二、基本要求 以“带行逻辑链接信息”的三元组顺序表表示稀疏矩阵,实现两个短阵相加、相减和相乘的运算。稀疏矩阵的输入形式采用三元组表示,而运算结果的矩阵则以通常的...
  • 稀疏矩阵运算器,以“带行逻辑链接信息”的三元组 顺序表表示稀疏矩阵, ~实现两个矩阵相加,相减或者相乘的运算。 ~稀疏矩阵的输入形式 采用三元组表示,运算结果矩阵 以通常阵列形式列出 CODE: /* 稀疏矩阵...
  • 实习4 稀疏矩阵运算器.zip
  • 可直接运行,数据结构 稀疏矩阵 数据结构 稀疏矩阵运算器

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,911
精华内容 4,764
关键字:

稀疏矩阵运算器

友情链接: CPK.rar