当前位置:   article > 正文

头歌(C语言)-数据结构与算法-稀疏矩阵的转置(共2关)_一般转置算法

一般转置算法

第1关:一般转置算法

任务描述

本关任务:实现稀疏矩阵的转置操作(采用一般转置算法,即按列序转置)。

相关知识

为了完成本关任务,你需要理解:1. 矩阵的压缩存储,2.稀疏矩阵的三元组顺序表存储表示,3.一般转置算法。

矩阵的压缩存储

矩阵的压缩存储是指:为多个值相同的非零元素只分配一个存储空间,对零元素不分配空间,从而节省存储空间。

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

稀疏矩阵是指非零元素的个数远远少于总的元素个数,且非零元素的分布没有规律。

稀疏矩阵的压缩存储就是只存储非零元素;且存储非零元素的值的同时,还需存储其所在的行和列。

于是,将非零元所在的行、列及其值构成一个三元组(i,j,v),且按行优先方式排列三元组,从而构成稀疏矩阵的三元组线性表,称为三元组表。

三元组表的存储方式有顺序存储和链式存储,从而可引出稀疏矩阵的两种压缩存储方式:三元组顺序表存储和十字链表存储。

 
  1. //三元组顺序表存储表示
  2. #define MAXSIZE 100
  3. typedef int datatype;
  4. typedef struct
  5. {
  6. int i,j;
  7. datatype v;
  8. }SPNode; //三元组类型
  9. typedef struct
  10. {
  11. int m,n,t; //矩阵的总行数、总列数及非零元个数
  12. SPNode data[MAXSIZE];
  13. }SPMatrix;

如:下面图1所示的稀疏矩阵A的三元组顺序表的数据存储情况如图2所示。

一般转置算法

先在矩阵A的三元组表A.data中找到第0列的非零元素存入转置阵B的三元组表B.data中,再找到第1列存入B.data中,……,这样得到的转置矩阵B的三元组表B.data中的元素必定按行优先存放。

如何在A.data中找第k列?

需对A.data扫描一遍,即:先比较A.data[0].j是否等于k,若相等,则将A.data[0]存入B.data中,接着继续比较下一个A.data[1].j, …… 。

编程要求

在右侧编辑器中补充代码,完成TransSMatrix函数,以实现稀疏矩阵的转置操作。具体要求如下:

* TransSMatrix:求稀疏矩阵A的转置阵B,采用一般转置算法(即按列序转置),稀疏矩阵采用三元组顺序表存储。

测试说明

平台会对你编写的代码进行测试,测试文件为step1/Main.cpp,可在右侧文件夹中进行查看。

输入输出格式: 输入格式: 第一行输入矩阵A的总行数、总列数及非零元个数 第二行按行序输入矩阵A的各个非零元素的行号、列号及值 输出格式: 先输出矩阵A的三元组表,再输出A的转置阵的三元组表。末尾换行。

测试输入: 5 5 6 //输入矩阵A的总行数、总列数及非零元个数 0 2 -9 0 4 5 1 0 -7 1 2 7 3 1 8 4 2 9 //按行序输入矩阵A的各个非零元素的行号、列号及值

预期输出: The Matrix A: (0,2,-9) (0,4,5) (1,0,-7) (1,2,7) (3,1,8) (4,2,9) The Transport Matrix of A: (0,1,-7) (1,3,8) (2,0,-9) (2,1,7) (2,4,9) (4,0,5) //末尾换行

代码:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "SparseMatrix.h"
  5. void input(SPMatrix &a)//输入采用三元组顺序表存储的矩阵
  6. {
  7. int p;
  8. scanf("%d%d%d",&a.m,&a.n,&a.t); //输入矩阵总行数、总列数和非零元素的个数
  9. for(p=0;p<a.t;p++)
  10. scanf("%d%d%d",&a.data[p].i,&a.data[p].j,&a.data[p].v);
  11. }
  12. void output(SPMatrix a)//输出矩阵的三元组表
  13. {
  14. int p;
  15. for(p=0;p<a.t;p++)
  16. printf("(%d,%d,%d)\n",a.data[p].i,a.data[p].j,a.data[p].v);
  17. }
  18. void TransSMatrix(SPMatrix a, SPMatrix &b)//一般转置,即:按列序转置
  19. {
  20. // 请在这里补充代码,完成本关任务
  21. /********** Begin *********/
  22. b=a;
  23. int num=0;
  24. for(int l=0;l<a.t;l++){
  25. for(int z=0;z<a.t;z++){
  26. if(a.data[z].j==l){
  27. b.data[num].i=a.data[z].j;
  28. b.data[num].j=a.data[z].i;
  29. b.data[num].v=a.data[z].v;
  30. num++;
  31. }
  32. }
  33. }
  34. /********** End **********/
  35. }

第2关:快速转置算法

任务描述

本关任务:实现稀疏矩阵的转置操作(采用快速转置算法)。

相关知识

为了完成本关任务,你需要理解:1. 稀疏矩阵的三元组顺序表存储表示,2.快速转置算法。

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

 
  1. //三元组顺序表存储表示
  2. #define MAXSIZE 100
  3. typedef int datatype;
  4. typedef struct
  5. {
  6. int i,j;
  7. datatype v;
  8. }SPNode; //三元组类型
  9. typedef struct
  10. {
  11. int m,n,t; //矩阵的总行数、总列数及非零元个数
  12. SPNode data[MAXSIZE];
  13. }SPMatrix;

快速转置算法

一般转置算法效率低的原因是通过对A.data扫描若干遍来找到第0列,第1列,……,共需扫描n遍。我们如果能直接确定A中每一个三元组在B中的位置,则对A.data扫描一遍即可。那么,如何确定A中每一个三元组在B.data中的位置?

设两个数组x[n]和y[n]。其中,x[i]表示A中第i列的非零元的个数,y[i]初始值表示A中第i列第一个非零元在B.data中的位置。

显然有:

 
  1. y[0]=0
  2. y[1]=y[0]+x[0]
  3. ……
  4. y[i]=y[i-1]+x[i-1]

接下来依次扫描A.data,先判断A.data[0],取出A.data[0].j用变量k保存(k=A.data[0].j),表示该三元组是A中第k列第一个非零元,则其在B.data中的位置为q=y[k],接着将该三元组存入B.data[q]中,然后y[k]++,以便将第k列的下一个非零元存放到B.data下一个位置;接着再判断A.data[1],……。

编程要求

在右侧编辑器中补充代码,完成FastTransSMatrix函数,以实现稀疏矩阵的转置操作。具体要求如下:

* FastTransSMatrix:求稀疏矩阵A的转置阵B,采用快速转置算法,稀疏矩阵采用三元组顺序表存储。

测试说明

平台会对你编写的代码进行测试,测试文件为step2/Main.cpp,可在右侧文件夹中进行查看。

输入输出格式: 输入格式: 第一行输入矩阵A的总行数、总列数及非零元个数 第二行按行序输入矩阵A的各个非零元素的行号、列号及值 输出格式: 先输出矩阵A的三元组表,再输出A的转置阵的三元组表。末尾换行。

测试输入: 5 5 6 //输入矩阵A的总行数、总列数及非零元个数 0 2 -9 0 4 5 1 0 -7 1 2 7 3 1 8 4 2 9 //按行序输入矩阵A的各个非零元素的行号、列号及值

预期输出: The Matrix A: (0,2,-9) (0,4,5) (1,0,-7) (1,2,7) (3,1,8) (4,2,9) The Transport Matrix of A: (0,1,-7) (1,3,8) (2,0,-9) (2,1,7) (2,4,9) (4,0,5) //末尾换行

代码:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "SparseMatrix.h"
  5. void input(SPMatrix &a)//输入采用三元组顺序表存储的矩阵
  6. {
  7. int p;
  8. scanf("%d%d%d",&a.m,&a.n,&a.t); //输入矩阵总行数、总列数和非零元素的个数
  9. for(p=0;p<a.t;p++)
  10. scanf("%d%d%d",&a.data[p].i,&a.data[p].j,&a.data[p].v);
  11. }
  12. void output(SPMatrix a)//输出矩阵的三元组表
  13. {
  14. int p;
  15. for(p=0;p<a.t;p++)
  16. printf("(%d,%d,%d)\n",a.data[p].i,a.data[p].j,a.data[p].v);
  17. }
  18. void FastTransSMatrix(SPMatrix a, SPMatrix &b)//快速转置
  19. {
  20. int p,q,i,k; int x[N],y[N];
  21. b.m=a.n; b.n=a.m; b.t=a.t;
  22. if(b.t==0)
  23. {
  24. printf("The matrix has no nonzero element!\n"); return;
  25. }
  26. for(i=0;i<a.n;i++) x[i]=0;
  27. for(p=0;p<a.t;p++) //求A中每一列非零元个数存放到x[ ]中
  28. {
  29. /********** Begin *********/
  30. x[a.data[p].j]++;
  31. /********** End **********/
  32. }
  33. y[0]=0;
  34. int num;
  35. for(i=1;i<a.n;i++)//求A中每一列的第一个非零元在B.data中的位置存放到y[ ]中
  36. {
  37. /********** Begin *********/
  38. y[i]=y[i-1]+x[i-1];
  39. /********** End **********/
  40. }
  41. for(p=0;p<a.t;p++) //扫描A.data,将A中每一三元组存放到B中恰当位置
  42. {
  43. /********** Begin *********/
  44. num=a.data[p].j;
  45. k=y[num];
  46. b.data[k].i=a.data[p].j;
  47. b.data[k].j=a.data[p].i;
  48. b.data[k].v=a.data[p].v;
  49. y[num]++;
  50. /********** End **********/
  51. }
  52. }

以上内容仅供参考哟,大家还需独立完成,巩固知识点^-^

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/611027
推荐阅读
相关标签
  

闽ICP备14008679号