稀疏矩阵快速转置
稀疏矩阵三元组快速转置(转poklau123写的很清楚)
稀疏矩阵三元组快速转置(转poklau123写的很清楚)关于稀疏矩阵的快速转置法,⾸先得明⽩其是通过对三元表进⾏转置。
如果误以为是对矩阵进⾏转置,毫⽆疑问就算你想破脑袋也想不出个所以然,别陷⼊死胡同了!对于⼀个三元表,⾏为i,列为j,值为v。
需将其i与j的值对调才能得到新的三元表,但是如果直接进⾏转换,得到的新的三元表的顺序是混乱的,不符合三元表的规则。
所以,课本⾸先介绍了⼀个⽤扫描来转置的算法(这个算法⽐较容易,在这⾥我就不说了),但是这个转置算法的时间复杂度太⾼,于是就有了接下来的快速转置算法。
要你对⼀个三元表进⾏步骤最少的转置,你可能会想,如果知道三元表中每⼀项在转置后的新的三元表中的位置,然后直接放进去,岂不是极⼤的缩⼩了时间复杂度?没错!快速转置法正是基于这种思想⽽设计的。
那么如何知道三元表中某⼀项的位置呢?在课本98页的a.data这个三元表可以看到,j为列号,在转置后即为新的三元表的⾏号,三元表正是按照⾏序进⾏排列的,⽽j=1有2个、j=2有2个、j=3有2个、j=4有1个、j=6有1个。
根据这些数据按照从⼩到⼤排列,j=1的项在新的三元表中应占据第1、2位,j=2的项在新的三元表中应占据第3、4位,j=3的项在新的三元表中应占据第5、6位,j=4应占据第7位,j=6应占据第8位。
接下来就轻松多了,转置的时候直接从第⼀项读起,读取其j值,⽐如课本中a.data这个三元表的第⼀项的j值为2,因为j=2占据第3、4位,所以应该从第三位开始放,接下来如果读取的某⼀项的j值也是2,就放在第4位。
因为j=2的项只有两个,所以第5位绝对不会被j=2的项占据,第5、6项本来就是留给j=3的。
再⽐如当读到j=6的那项时,第8位是留给它的,就可以直接放进第8位了。
这样,读取每⼀项,都能在三元表中找到相应的位置,这就是稀疏矩阵快速转置的原理。
当然,上⾯只是快速转置的原理,要实现它,就要设计算法来实现了。
稀疏矩阵的快速转置算法
稀疏矩阵的快速转置算法
稀疏矩阵的快速转置算法可以使用压缩存储的方式来实现。
稀疏矩阵通常包含很多零元素,因此压缩存储可以极大地减少存储空间和计算时间。
压缩存储可以使用两个数组来表示稀疏矩阵,一个存储非零元素的值,另一个存储非零元素在原始矩阵中的行列索引。
假设原始矩阵的行数为m,列数为n,稀疏矩阵中非零元素的个数为k。
转置算法的步骤如下:
1. 创建一个新的稀疏矩阵,行数为n,列数为m,非零元素个数为k。
2. 初始化一个长度为n的数组col_ptr,用于记录每列的第一个非零元素在转置矩阵中的索引。
3. 通过遍历原始稀疏矩阵的每个非零元素,将其值存储到转置矩阵的非零元素数组中,并根据其列索引更新col_ptr数组。
4. 根据col_ptr数组,计算每列非零元素在转置矩阵非零元素数组中的起始位置,并将其存储到col_ptr数组中。
5. 返回转置矩阵。
这个算法的时间复杂度为O(k),空间复杂度为O(n+m+k)。
通过压缩存储和利用非零元素在矩阵中的位置信息,这种算法可以高效地实现稀疏矩阵的快速转置。
4.3.4 稀疏矩阵-快速转置算法实例演示
转置三元组
实例演示
0
0
16
0
3
22
0
5
-16
1
1
12
1
2
3
2
3
-8
4
0
91
6
2
15
行三元组A
0
1
2
3
4
5
num
2
1
2
2
0
1
k
1
3
4
7
7
8
0
0
1
2
0
4
1
1
16
91
12
3
3
3
5
0
2
0
22
-8
-16
转置三元组
实例演示
0
0
16
0
3
22
0
5
-16
1
1
12
1
2
3
2
3
-8
4
0
91
6
2
15
行三元组A
0
1
2
3
4
5
数组
1
数组的基本概念
2
特殊矩阵
3
稀疏矩阵
Content
A 稀疏矩阵的抽象数据类型
C 稀疏矩阵的快速转置算法
B 稀疏矩阵的两种转置算法
D 快速转置算法实例演示
PART THREE
D 快速转置算法实例演示
16 0
0 22 0 −16
0 12 3
0 0
0
0
0
0 −8 0
0
0
稀疏矩阵快速转置算法
稀疏矩阵快速转置算法
稀疏矩阵快速转置算法是一种用于高效地将稀疏矩阵进行转置的算法。
稀疏矩阵是指其中大部分元素为零的矩阵。
下面是一种常见的稀疏矩阵快速转置算法,称为CRS(Compressed Row Storage)格式:
1. 首先,遍历原始矩阵,统计每列非零元素的个数,并记录每个非零元素在转置后矩阵中的位置。
2. 创建一个长度为列数的数组col_ptr,用于记录每一列非零元素在转置后矩阵中的起始位置。
3. 初始化col_ptr数组,使得col_ptr[i]表示第i列在转置后矩阵中的起始位置,初始值为0。
4. 再次遍历原始矩阵,将每个非零元素按照其在转置后矩阵中的位置放入对应的位置。
对于原始矩阵中的每个非零元素A[i][j],找到其在转置后矩阵中的位置,即col_ptr[j] + 1,将该元素放入转置后矩阵的该位置。
更新col_ptr[j],使其加1,以便下一个非零元素能够放入正确的位置。
5. 完成转置后,得到转置后的稀疏矩阵。
这种算法的时间复杂度为O(n + nz),其中n是原始矩阵的列数,nz是原始矩阵的非零元素个数。
该算法通过压缩存储和避免无效操作,能够高效地进行稀疏矩阵的转置。
1。
稀疏矩阵快速转置
/* Note:Your choice is C IDE */#include "stdio.h"#define MAXSIZE 12500typedef struct{int i,j; //该非零元的行下标和列下标int e;}Triple;typedef struct{Triple data[MAXSIZE+1];//非零元三元组表,data[0]未用int mu,nu,tu; //矩阵的行数,列数和非零元个数}TSMatrix;void CreateSMatrix(TSMatrix *M){int p,q,m,n,r=1;int SMatrix[10][10];printf("请输入稀疏矩阵的行数和列数\n");scanf("%d",&m);scanf("%d",&n);printf("请输入稀疏矩阵\n");for(p=1;p<=m;p++)scanf("%d",&SMatrix[p][q]);for(p=1;p<=m;p++)for(q=1;q<=n;q++)if(SMatrix[p][q]!=0){M->data[r].i=p;M->data[r].j=q;M->data[r].e=SMatrix[p][q];r++;}M->mu=m;M->nu=n;M->tu=r;}void PrintSMatrix(TSMatrix *M){int p,q;int SMatrix[10][10];for(p=1;p<=M->mu;p++)for(q=1;q<=M->nu;q++)SMatrix[p][q]=0;SMatrix[M->data[p].i][M->data[p].j]=M->data[p].e;printf("result is:\n");for(p=1;p<=M->mu;p++){for(q=1;q<=M->nu;q++)printf("%3d",SMatrix[p][q]);printf("\n");}}void TransposeSMatrix(TSMatrix M,TSMatrix *T){/*int col,p,q;T->mu=M.nu;T->nu=M.mu;T->tu=M.tu;if(T->tu){q=1;for(col=1;col<=M.nu;col++)for(p=1;p<=M.tu;p++)if(M.data[p].j==col){T->data[q].i=M.data[p].j;T->data[q].j=M.data[p].i;T->data[q].e=M.data[p].e;++q;}}*/int col,p,q,t;int num[10],cpot[10];T->mu=M.nu;T->nu=M.mu;T->tu=M.tu;if(T->tu){for(col=1;col<=M.nu;++col) num[col]=0;for(t=1;t<=M.tu;++t) ++num[M.data[t].j];cpot[1]=1;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];}}}void main(){TSMatrix M,T;CreateSMatrix(&M);TransposeSMatrix(M,&T);PrintSMatrix(&T);}。
稀疏矩阵快速转置k数组计算
稀疏矩阵快速转置k数组计算
稀疏矩阵是指大部分元素为零的矩阵,而只有少数元素非零。
在计算机科学领域中,稀疏矩阵常常用于表示大规模数据中的稀疏性,以节省存储空间和提高计算效率。
在处理稀疏矩阵时,矩阵的转置是一个常见的操作,可以帮助我们在不同的计算任务中更方便地处理数据。
为了实现稀疏矩阵的快速转置,我们可以利用稀疏矩阵的特点,采用一种高效的算法来实现。
其中,k数组是一种常用的数据结构,可以帮助我们在转置操作中更高效地处理稀疏矩阵。
在进行稀疏矩阵的转置时,我们首先需要了解稀疏矩阵的存储格式。
常见的稀疏矩阵存储格式包括压缩稀疏行(CSR)格式和压缩稀疏列(CSC)格式。
在CSR格式中,矩阵的非零元素按行依次存储,而在CSC格式中,矩阵的非零元素按列依次存储。
对于稀疏矩阵的转置操作,我们可以利用k数组来实现。
k数组是一种紧凑的数据结构,可以帮助我们高效地处理稀疏矩阵的转置。
在进行转置操作时,我们可以先遍历原始矩阵的非零元素,然后根据这些非零元素的位置信息,将它们按照列的顺序重新组织,从而得到转置后的稀疏矩阵。
通过使用k数组来实现稀疏矩阵的快速转置,我们可以在保持数据结构紧凑的同时,提高转置操作的效率。
这种方法不仅可以节省存
储空间,还可以加快计算速度,特别是在处理大规模稀疏矩阵时,具有明显的优势。
总的来说,利用稀疏矩阵和k数组结合的方法,可以帮助我们更高效地处理大规模数据中的稀疏性,提高计算效率和节省存储空间。
通过深入理解稀疏矩阵的特点和转置操作的原理,我们可以更好地利用这些数据结构和算法,为计算机科学领域的相关应用提供更好的支持和帮助。
三元组快速转置算法
三元组快速转置算法
三元组快速转置算法是一种用于将稀疏矩阵的三元组表示转置的算法。
稀疏矩阵是指大部分元素为0的矩阵,而三元组表示是一种常用的稀疏矩阵存储方式。
三元组表示将稀疏矩阵中非零元素的位置和对应的值存储起来,通常由三个数组来表示:行索引数组(row),列索引数组(col)和值数组(val)。
每个非零元素都有一个对应的行索引、列索引和值。
快速转置算法的基本思想是通过遍历三元组表示中的元素,将其按照列索引重新排序,并计算每个列索引在转置后的矩阵中的起始位置。
然后再遍历三元组表示,将每个元素插入到转置后相应的位置。
这样就完成了矩阵转置的过程。
具体实现快速转置算法的步骤如下:
1. 统计每个列索引出现的次数,得到每个列索引在转置后的矩阵中的起始位置。
2. 计算每个列索引在转置后的矩阵中的终止位置。
3. 根据起始位置和终止位置,确定每个非零元素在转置后的矩阵中的位置。
4. 将每个非零元素插入到转置后的矩阵中相应的位置。
快速转置算法的时间复杂度取决于稀疏矩阵中非零元素的个数和矩阵的维度。
相比于其他转置算法,快速转置算法在处理大规模稀疏矩阵时具有较高的效率。
需要注意的是,三元组表示和快速转置算法都是用于稀疏矩阵的
存储和操作,对于密集矩阵则没有优势。
稀疏矩阵的快速转置算法(c语言)详解
稀疏矩阵的快速转置算法(C语言)详解稀疏矩阵是指大部分元素为零的矩阵,只有少数元素为非零的矩阵。
在实际的计算机科学和工程应用中,稀疏矩阵经常出现,比如在图形图像处理、科学计算和数据分析等领域。
而稀疏矩阵的快速转置算法是针对稀疏矩阵的一种重要算法,它可以有效地将稀疏矩阵进行转置,从而方便后续的计算和操作。
快速转置算法的实现是计算机科学中一个经典的问题,对于稀疏矩阵来说更是如此。
在本文中,我们将从深度和广度两个方面对稀疏矩阵的快速转置算法进行全面评估,探讨其原理和实现细节,并对其进行详细解析。
让我们简要了解一下稀疏矩阵的结构和特点。
稀疏矩阵通常由三个部分组成:行数组、列数组和值数组。
行数组存储非零元素所在的行号,列数组存储非零元素所在的列号,而值数组则存储非零元素的值。
由于稀疏矩阵的特殊性,传统的矩阵转置算法并不适用于稀疏矩阵,因此需要设计一种特殊的快速转置算法来处理稀疏矩阵。
在对快速转置算法进行详细解析之前,让我们先来看一下转置操作的定义。
对于一个矩阵A,其转置矩阵记为A^T,即A的行与列互换。
在稀疏矩阵的转置操作中,我们需要将原始矩阵中的非零元素按照列索引进行重新排列,同时保持其在矩阵中的相对位置不变。
实现稀疏矩阵的快速转置算法涉及到矩阵的数据结构和算法设计方面的知识。
传统的方法是通过对每个非零元素进行遍历,并将其插入到新矩阵的相应位置中,但这种方法的时间复杂度较高。
而快速转置算法通过巧妙的数据结构设计和算法优化,可以在更短的时间内完成转置操作,提高了算法的效率。
在C语言中实现稀疏矩阵的快速转置算法需要考虑到内存管理、指针操作和数据结构的设计等方面。
通常情况下,可以使用链表等数据结构来表示稀疏矩阵,同时利用指针进行快速的遍历和操作。
在实际的编程过程中,还需要注意对内存的合理分配和释放,以避免内存泄漏和溢出的问题。
为了更好地理解稀疏矩阵的快速转置算法,我们可以通过具体的代码实现来加深对算法原理的理解。
稀疏矩阵快速转置 数据结构实验报告
稀疏矩阵快速转置数据结构实验报告一、实验目的1、掌握稀疏矩阵的存储方式;2、掌握稀疏矩阵的快速转置算法;3、进一步了解和巩固线性表和链表的相关知识。
二、实验内容1、根据课本内容和参考资料,设计两种不同的存储稀疏矩阵的结构体,并分别实现稀疏矩阵的快速转置操作;2、实现输出稀疏矩阵、打印转置后的稀疏矩阵、以及转置前后两个稀疏矩阵在内存中的存储情况。
三、实验原理1、稀疏矩阵的存储稀疏矩阵指的是矩阵中绝大多数元素为零的矩阵,依据存储方式,目前主要有两种实现方法:顺序表和链表。
(1)顺序表顺序表的存储方式如下:typedef struct{int arr[MAXSIZE]; // 一维数组表示矩阵int rows; // 矩阵共有 rows 行int cols; // 矩阵共有 cols 列int nums; // 矩阵中不为零的元素共有 nums 个}TSMatrix;其中,数组 arr 的长度为 MAXSIZE,每个元素保存矩阵中某个元素的值,且元素的下标按行优先排列,例如,在一个5×5 的矩阵中,a23 可以表示成 a[(2-1)×5+3-1],其中 2-1 代表该元素所在行的下标,3-1 代表该元素所在列的下标。
(2)链表链式存储的特点在于元素之间存在指针联系,节点中保存三元组(row、col、val),其中 row 表示该元素所在的行,col 表示该元素所在的列,val 表示该元素的值,next 指针表示该元素的下一个节点。
2、稀疏矩阵转置稀疏矩阵转置的基本思想是将原矩阵中非零元素的行和列对换。
转置后的矩阵中行和列的值对应变换,对应的非零元素也跟着变化。
1、初始化转置矩阵;2、遍历原矩阵中的元素,将其转置后按行优先的顺序插入转置矩阵;3、输出转置矩阵。
链表转置的步骤如下:四、实验步骤1、根据上述原理,设计 2 种结构体 TSMatrix 和 LinkMatrix,分别完成快速转置算法;2、封装 tranverse_TMatrix 和 tranverse_LinkMatrix 两个函数,并设计测试用例验证结果。
三元组稀疏矩阵快速转置C语言算法
下面就是(算式 1)式中矩阵 M 的(5 行 6 列共有)8 个非零元 素的三元组表示:
四、快速转置算法
这两种算法的函数中,a 是已知的三元组表,为了使函数 得到转置后新的三元组表b, 这里使用的是传址调用的形参*b。
按照 a.data 中三元组的次序进行转置。转置后的元素 不连续存放,直接放到 b->data 中应有的位置上,这样既可 以避免元素移动,又只需对 a.data 扫描一次。为了确定矩阵 M 中的每一列(即 N 中每一行)的第一个非零元素在 b->data 中 应有的位置,需要先求得矩阵 M 中的每一列中非零元素的个 数。为此,需设置两个数组 num[1..n]和 pot[1..n],分别存 放在矩阵 M 中每一列的非零元素个数和每一列第 1 个非零元素 在 b->data 中的位置,即
二数组的三元组表示与稀疏矩阵在实际应用中往往会遇到一种大多数元素的值为零的矩阵只有少部分为非零元素这些非零元素在矩阵中的分布又没有一定的规?我们把它记作零元素个数非零元素个数即零元素个数远远大于非零元素个数
专业视窗
决策管理
Policy & Management
三元组稀疏矩阵快速转置 C 语言算法
徐光联
num[a.data[k].j]); }
pot[1]=0; for (col=2; col<=a.n; col++) { pot[col]=pot[col-1]+num[col-1]; printf("pot[%d]=%d\n",col,pot[col]); } for (p=0;p<a.t;p++) { col=a.data[p].j; q=pot[col]; b->data[q].i=a.data[p].j; b->data[q].j=a.data[p].i; fastran ( b->data[q].v=a.data[p].v; pot[col]++;
java稀疏矩阵快速转置(精品文档)_共7页
置后送出)。
4.【高级语言代码】//定义稀疏矩阵类SparseMatrixclass SparseMatrix {//稀疏矩阵的行数/列数/非零元素数int Rows,Cols,Terms;//动态分配结构体数组(三元组表)public Trituple smArray[];//构造函数:稀疏矩阵的行数/列数/非零元素数public SparseMatrix(int MaxRow,int MaxCol,int MaxTerms,int a[][],float v[]) {//稀疏矩阵的初始化Rows=MaxRow;Cols=MaxCol;Terms=MaxTerms;smArray=new Trituple[MaxTerms]; //三元组表for(int i=0;i<MaxTerms;i++) {Trituple tmp=new Trituple(a[i][0],a[i][1],v[i]); //构成一行smArray[i]=tmp; //加入表中}}//重载构造方法:空三元组public SparseMatrix(int Rows,int Cols,int Terms) {this.Rows=Rows; //这里this不可省略this.Cols=Cols;this.Terms=Terms;this.smArray=new Trituple[Terms]; //空三元组表for(int i=0;i<this.Terms;i++) { //不初始化不能用。
Trituple tmp=new Trituple(0,0,0.0f); //构成一行smArray[i]=tmp; //加入表中(这里为什么可以省略this?)}}//显示输出稀疏矩阵void display(){int i,j,k;System.out.println("稀疏矩阵的行数 "+Rows);System.out.println("稀疏矩阵的列数 "+Cols);//按先行后列顺序输出矩阵for(i=0;i<Rows;i++) {for(j=0;j<Cols;j++) {for(k=0;k<Terms;k++) //查三元组表if(i==smArray[k].row&&j==smArray[k].col){System.out.print(smArray[k].value+" ");break; //打断k循环}if(k==Terms) System.out.print("0 ");}System.out.println(); //换行}}//稀疏矩阵的快速转置方法(将自身转置后送出)public SparseMatrix FastmTrans(){//转置矩阵的列数,行数和非零元素个数(交换行列数)SparseMatrix b=new SparseMatrix(Cols,Rows,Terms); //构造方法二//分配辅助数组int rowSize[] = new int[this.Cols];int rowStart[] = new int[this.Cols];//统计每列的非零元素个数for (int i = 0; i < this.Cols; i++)rowSize[i] = 0;for (int i = 0; i < this.Terms; i++ )rowSize[this.smArray[i].col]++;//转置后,每行第一个非零元素在三元组表中的位置rowStart[0] = 0;for (int i = 1; i < this.Cols; i++ )rowStart[i] = rowStart[i-1]+rowSize[i-1];//快速转置for (int i = 0; i < this.Terms; i++ ) {int j = rowStart[this.smArray[i].col];//首先遇到的总是本行第一个非零元素b.smArray[j].row = this.smArray[i].col;b.smArray[j].col = this.smArray[i].row;b.smArray[j].value = this.smArray[i].value;//为本行的下一个非零元素定好位置rowStart[this.smArray[i].col]++;}return b;}} //稀疏矩阵类SparseMatrix结束(四)、程序的输入输出和运行结果截屏程序运行结果截屏:。
三元组表示稀疏矩阵的转置(一般算法和快速算法)
一、设计要求1.1 问题描述稀疏矩阵是指那些多数元素为零的矩阵。
利用稀疏特点进行存储和计算可以大大节省存储空间,提高计算效率。
求一个稀疏矩阵A的转置矩阵B。
1.2需求分析(1)以“带行逻辑链接信息”的三元组顺序表表示稀疏矩阵,实现稀疏矩阵的转置运算。
(2)稀疏矩阵的输入形式采用三元组表示,运算结果则以通常的阵列形式列出。
(3)首先提示用户输入矩阵的行数、列数、非零元个数,再采用三元组表示方法输入矩阵,然后进行转置运算,该系统可以采用两种方法,一种为一般算法,另一种为快速转置算法。
(4)程序需要给出菜单项,用户按照菜单提示进行相应的操作。
二、概要设计2.1存储结构设计采用“带行逻辑链接信息”的三元组顺序表表示矩阵的存储结构。
三元组定义为:typedef struct{int i;//非零元的行下标int j;//非零元的列下标ElemType e; //非零元素值}Triple;矩阵定义为:Typedef struct{Triple data[MAXSIZE+1]; //非零元三元组表int rpos[MAXRC+1]; //各行第一个非零元的位置表int mu,nu,tu; //矩阵的行数、列数和非零元个数}RLSMatrix;例如有矩阵A,它与其三元组表的对应关系如图2.2 系统功能设计本系统通过菜单提示用户首先选择稀疏矩阵转置方法,然后提示用户采用三元组表示法输入数据创建一个稀疏矩阵,再进行矩阵的转置操作,并以通常的阵列形式输出结果。
主要实现以下功能。
(1)创建稀疏矩阵。
采用带行逻辑连接信息的三元组表表示法,提示用户输入矩阵的行数、列数、非零元个数以及各非零元所在的行、列、值。
(2)矩阵转置。
<1>采用一般算法进行矩阵的转置操作,再以阵列形式输出转置矩阵B。
<2>采用快速转置的方法完成此操作,并以阵列形式输出转置矩阵B。
三、模块设计3.1 模块设计程序包括两个模块:主程序模块、矩阵运算模块。
三元组压缩存储结构的稀疏矩阵的运算快速转置
三元组压缩存储结构的稀疏矩阵的运算快速转置在计算机科学和数学领域中,稀疏矩阵是一种在大部分元素为零的矩阵。
由于其大部分元素为零,因此在存储和运算时存在着一些挑战。
为了解决这一问题,人们提出了三元组压缩存储结构,这种存储结构能够有效地压缩稀疏矩阵,并且能够实现快速的运算转置。
1.稀疏矩阵稀疏矩阵是一种大部分元素为零的矩阵,与之相对应的是稠密矩阵,其大部分元素为非零值。
稀疏矩阵通常在图像处理、文本处理、网络分析等领域中得到广泛应用。
然而,由于大部分元素为零,传统的存储方式会导致存储空间的浪费。
人们提出了三元组压缩存储结构,以解决稀疏矩阵存储的问题。
2.三元组压缩存储结构三元组压缩存储结构是一种用于表示稀疏矩阵的存储格式。
它采用三个数组来分别存储矩阵的非零元素的行坐标、列坐标和数值。
由于只需存储非零元素的信息,因此能够有效地压缩存储空间。
三元组压缩存储结构还能够实现快速的随机访问,这是由于它将矩阵的元素位置和数值分开存储,使得在进行运算时能够更为高效。
3.稀疏矩阵的运算稀疏矩阵的运算是对稀疏矩阵进行加法、减法、乘法等操作的过程。
在进行稀疏矩阵的运算时,三元组压缩存储结构能够显著提高计算效率。
这是由于在进行运算时,只需考虑非零元素,而无需考虑大量的零元素,从而减少了计算的复杂度。
4.稀疏矩阵的快速转置稀疏矩阵的转置是将矩阵的行和列交换,同时保持非零元素的位置和数值不变。
在传统的存储方式下,稀疏矩阵的转置操作相对复杂且耗时。
然而,采用三元组压缩存储结构后,稀疏矩阵的快速转置变得十分简便。
通过交换三元组中的行坐标和列坐标,即可完成稀疏矩阵的快速转置操作。
5.个人观点和理解我认为三元组压缩存储结构的出现,极大地解决了稀疏矩阵在存储和运算中的效率问题。
通过将矩阵的非零元素信息进行压缩存储,不仅节省了存储空间,同时也提高了计算效率。
在实际应用中,三元组压缩存储结构能够更好地满足对存储空间和计算效率有较高要求的场景,为稀疏矩阵的处理提供了更为便利和高效的途径。
稀疏矩阵转置+快速转置
稀疏矩阵转置+快速转置稀疏矩阵转置Description稀疏矩阵的存储不宜⽤⼆维数组存储每个元素,那样的话会浪费很多的存储空间。
所以可以使⽤⼀个⼀维数组存储其中的⾮零元素。
这个⼀维数组的元素类型是⼀个三元组,由⾮零元素在该稀疏矩阵中的位置(⾏号和列号对)以及该元组的值构成。
矩阵转置就是将矩阵⾏和列上的元素对换。
现在就请你对⼀个稀疏矩阵进⾏转置。
以下是稀疏矩阵转置的算法描述:图:稀疏矩阵转置的算法描述Input输⼊的第⼀⾏是两个整数r和c(r*c <= 12500),分别表⽰⼀个包含很多0的稀疏矩阵的⾏数和列数。
接下来有r⾏,每⾏有c个整数,表⽰这个稀疏矩阵的各个元素。
Output输出c⾏,每⾏有r个整数,每个整数后跟⼀个空格。
该结果为输⼊稀疏矩阵的转置矩阵。
Sample Input6 70 12 9 0 0 0 00 0 0 0 0 0 0-3 0 0 0 0 14 00 0 24 0 0 0 00 18 0 0 0 0 015 0 0 -7 0 0 0Sample Output0 0 -3 0 0 1512 0 0 0 18 09 0 0 24 0 00 0 0 0 0 -70 0 0 0 0 00 0 14 0 0 00 0 0 0 0 0HINT提⽰:严⽼师纸质书中⽤union类型来表⽰稀疏矩阵类型,这是有问题的,应该使⽤struct来表⽰该类型。
注意理解为什么转置算法中,以列从⼩到⼤来进⾏转置。
实际上只需⼀个循环就能够完成转置⽽不需将列从⼩到⼤来处理,转置后的矩阵虽然是正确的但却乱掉了,以⾄于在各种处理中会增加复杂。
(其实就本题⽽⾔,如果不以列从⼩到⼤处理将导致输出困难,输出的复杂度增加)总结:矩阵是⼀个应⽤很⼴泛的⼯具和课题。
看看《⿊客帝国》就知道了。
现在初步给⼤家介绍矩阵的操作,以后有机会还会详细讨论矩阵的。
1 #include <stdio.h>2 #include <string.h>3 #include <iostream>4 #include <string>5 #include <math.h>6 #include <algorithm>7 #include <vector>8 #include <stack>9 #include <queue>10 #include <set>11 #include <map>12 #include <math.h>13const int INF=0x3f3f3f3f;14 typedef long long LL;15const int mod=1e9+7;16const int maxn=1e4+10;17using namespace std;1819 typedef struct20 {21int row;22int col;23int val;24 }Triple;2526 typedef struct27 {28 Triple date[maxn];29int rows;30int cols;31int nums;32 }TSMatrix;3334void TransposeTSMatrix(TSMatrix *A,TSMatrix *B)35 {36 B->rows=A->cols;37 B->cols=A->rows;38 B->nums=A->nums;39if(B->nums > 0)40 {41int cnt=0;42for(int i=1;i<=A->cols;i++)43 {44for(int j=1;j<=A->nums;j++)45 {46if(A->date[j].col==i)47 {48 cnt++;49 B->date[cnt].row=A->date[j].col;50 B->date[cnt].col=A->date[j].row;51 B->date[cnt].val=A->date[j].val;52 }53 }54if(cnt == B->nums)55break;56 }57 }58return ;59 }6061int main()62 {63 TSMatrix A,B;64 scanf("%d %d",&A.rows,&A.cols);65 A.nums=0;66for(int i=1;i<=A.rows;i++)67 {68for(int j=1;j<=A.cols;j++)69 {70int x;71 scanf("%d",&x);72if(x)73 {74 A.nums++;75 A.date[A.nums].row=i;76 A.date[A.nums].col=j;77 A.date[A.nums].val=x;78 }79 }80 }81 TransposeTSMatrix(&A,&B);82int cnt=1;83for(int i=1;i<=B.rows;i++)84 {85for(int j=1;j<=B.cols;j++)86 {87int a,b;88 a=B.date[cnt].row;89 b=B.date[cnt].col;90if(a==i&&b==j)91 {92 printf("%d ",B.date[cnt].val);93 cnt++;94 }95else96 printf("%d ",0);97 }98 printf("\n");99 }100return0;101 }稀疏矩阵快速转置Description稀疏矩阵的存储不宜⽤⼆维数组存储每个元素,那样的话会浪费很多的存储空间。
稀疏矩阵快速转置k数组计算
稀疏矩阵快速转置k数组计算稀疏矩阵指的是矩阵中绝大多数元素为0的矩阵,而k数组计算则是指对一个长度为n的数组进行k次计算的操作。
下面将分别介绍稀疏矩阵快速转置和k 数组计算。
一、稀疏矩阵快速转置稀疏矩阵的转置是指将矩阵的行和列互换,即原矩阵中第i行第j列的元素在转置后变成第j行第i列的元素。
对于一般的矩阵,转置需要将所有元素都遍历一遍,时间复杂度为O(n^2)。
但对于稀疏矩阵,由于绝大多数元素为0,因此只需要遍历非零元素,时间复杂度可以降至O(k),其中k为非零元素的个数。
稀疏矩阵快速转置的算法如下:1. 遍历原矩阵,统计每一列非零元素的个数,得到一个数组colCount,其中colCount[i]表示第i列非零元素的个数。
2. 根据colCount数组,得到每一列非零元素在转置后的位置,得到一个数组colStart,其中colStart[i]表示第i列非零元素在转置后的起始位置。
3. 遍历原矩阵,将每一个非零元素放到转置后的对应位置,即将原矩阵中第i行第j列的元素放到转置后的第j行第i列的位置。
4. 根据colCount和colStart数组,得到转置后矩阵每一行的非零元素个数和起始位置。
5. 将转置后的矩阵存储在稀疏矩阵的数据结构中。
二、k数组计算k数组计算是指对一个长度为n的数组进行k次计算的操作,其中每次计算需要对数组中的所有元素进行一定的运算。
对于一般的算法,时间复杂度为O(k*n),其中k为计算次数,n为数组长度。
但对于一些特殊的情况,可以通过一些技巧将时间复杂度降至O(n)。
一种常见的k数组计算优化算法是前缀和算法。
该算法的思想是,先计算出数组的前缀和数组prefixSum,其中prefixSum[i]表示原数组中前i个元素的和。
然后对于每一次计算,只需要对prefixSum数组进行一定的修改,即可得到新的数组。
具体实现如下:1. 计算前缀和数组prefixSum。
2. 对于每一次计算,将prefixSum数组中的某些元素进行修改,得到新的数组。
稀疏矩阵的快速转置算法_数据结构(C语言)_[共2页]
第4章数组和字符串55 换元素行列号后依次保存到B的行三元组表中。
步骤2:对A的行三元组表进行第2次扫描,找到列下标j = 1的所有三元组<i, 1, a i1>,交换元素行列号后依次保存到B的行三元组表中。
……步骤n:对A的行三元组表进行第n次扫描,找到列下标j = n−1的所有三元组<i, n−1, a i,n−1>,交换元素行列号后依次保存到B的行三元组表中。
上述算法对A的行三元组表进行了最多n次扫描,时间复杂度为O(t×n)。
图4.8是第二种简单转置算法过程示例。
图4.8 第二种简单转置算法过程4.4.3 稀疏矩阵的快速转置算法上一小节介绍的两种简单稀疏矩阵转置算法都比较耗时。
通过增加适量额外存储空间,存储预先计算的辅助信息,能够实现快速稀疏矩阵转置,其算法时间复杂度可以降低至O(n+t)。
假设按照行优先存储稀疏矩阵非零元素,稀疏矩阵A进行转置后的结果存储到稀疏矩阵B中。
实现快速转置算法需要借助两个一维辅助数组num和k,这两个数组长度都为n(稀疏矩阵A的列数)。
数组num的元素num[j] 统计稀疏矩阵A中列号为j的非零元素个数。
只需要对A的行三元组表进行一次扫描,即可统计出A的每一列非零元素个数,程序段如下所示。
for(int j=0; j<n; j++) num[j] = 0; /* num初始化*/for(int i=0; i<t; i++) num[A.table[i].col]++;数组k的元素k[j] 统计稀疏矩阵A中列号从0到j−1列的非零元素个数总和,该值也表示j列第一个非零元素在转置稀疏矩阵B的行三元组表中的位置。
只需要对辅助数组num进行一次扫描,即可完成数组k中各元素值的计算,程序段如下所示。
for(int j = 0; j<n; j++) k[j] = 0; /* k初始化*/for(int j = 1; j<n; j++) k[j] = k[j-1] + num[j-1];计算数组num和k的两个程序段时间复杂度为O(n+t)。
基于三元组表表示的稀疏矩阵的快速转置算法及其改进
基于三元组表表示的稀疏矩阵的快速转置算法及其改进摘要:介绍基于三元组表表示的稀疏矩阵的快速转置算法,此算法在转置前需要先确定原矩阵中各列第一个非零元在转置矩阵中的位置,在此使用2个数组作为辅助空间,为了减少算法所需的辅助空间,通过引入2个简单变量提出一种改进算法。
该改进算法在时间复杂度保持不变的情况下,空间复杂度比原算法节省一半。
需求分析:矩阵作为许多科学与工程计算的数据对象,必然是计算机处理的数据对象之一。
在实际应用中,常会遇到一些阶数很高,同时又有许多值相同的元素或零元素的矩阵,在这类矩阵中,如果值相同的元素或零元素在矩阵中的分配没有规律,则称之为稀疏矩阵。
为了节省存储空间,常对稀疏矩阵进行压缩存储。
压缩存储的基本思想就是:对多个值相同的元素只分配1个存储空间,对零元素不分配存储空间。
换句话说,就是只存储稀疏矩阵中的非零元素。
稀疏矩阵可以采取不同的压缩存储方法,对于不同的压缩存储方法,矩阵运算的实现也就不同。
1.稀疏矩阵的三元组表表示法根据压缩存储的基本思想,这里只存储稀疏矩阵中的非零元素,因此,除了存储非零元的值以外,还必须同时记下它所在行和列的位置(i,j),即矩阵中的1个非零元aij由1个三元组(i,j,aij)惟一确定。
由此可知,稀疏矩阵可由表示非零元的三元组表及其行列数惟一确定。
对于稀疏矩阵的三元组表采取不同的组织方法即可得到稀疏矩阵的不同压缩存储方法,用三元组数组(三元组顺序表)来表示稀疏矩阵即为稀疏矩阵的三元组表表示法。
三元组数组中的元素按照三元组对应的矩阵元素在原矩阵中的位置,以行优先的顺序依次存放。
三元组表的类型说明如下:# define MAXSIZE 1000 /*非零元素的个数最多为1000*/typedef struct{int row,col; /*该非零元素的行下标和列下标*/ElementType e; /*该非零元素的值*/}Triple;typedef struct{Triple data[MAXSIZE+1]; /*非零元素的三元组表,data[0]未用*/int m,n,len; /*矩阵的行数、列数和非零元素的个数*/}TSMatrix;2.稀疏矩阵的快速转置算法待转置矩阵source和转置后矩阵dest分别用三元组表A和B表示,依次按三元组表A中三元组的次序进行转置,转置后直接放到三元组表B的正确位置上。
稀疏矩阵的快速转置
实验名称:实现稀疏矩阵的基本运算一、实验目的:熟悉数组的有关概念,掌握稀疏矩阵的三元组存储结构及其基本运算算法。
二、实验内容:键盘任意输入一个稀疏矩阵A(m*n),采用三元组存储方法求其转置矩阵B (n*m),并用快速转置算法实现该操作。
三、算法思想与算法描述:为了确定相应位置,转置前必须求得稀疏矩阵A的三元组中每列非零元的个数,从而求得每列的第一个非零元在转置矩阵B的三元组中(行)的位置。
为此需要两个辅助数组num和cpot,num[col]表示矩阵A的第col列中非零元的个数,cpot[col]矩阵A的第col列的第一个非零元在矩阵B中的恰当位置,且显然有:cpot[1]=1; cpot[col]= cpot[col-1]+ num[col-1] 2≤ col≤ A的列四、实验步骤与算法实现:#include<stdio.h>#include<malloc.h>#include<stdlib.h>typedef int ElemType;int a,b;#define MaxSize 100typedef struct{int i;int j;ElemType d;}TupNode;typedef struct{int mu;int nu;int tu;TupNode data[MaxSize];}TSMatrix;TSMatrix *creatarray(TSMatrix *M){int m,n,p=1;int c;printf("请输入数组 A:\n");for(m=1;m<=a;m++)for(n=1;n<=b;n++){scanf("%d",&c);if(c!=0){M->data[p].d=c;M->data[p].i=m;M->data[p].j=n;p++;}}M->tu=p;M->mu=a;M->nu=b;printf("原来的三元组为:\n");for(m=1;m<=M->tu;m++)printf("%3d%3d%3d\t",M->data[m].i,M->data[m].j,M->data[m].d);printf("\n");return M;}TSMatrix *fasttrans(TSMatrix *M,TSMatrix *T){int p,col,q,t,m;int num[100];int cpot[100];T->mu=M->nu;T->nu=M->mu;T->tu=M->tu;if(T->tu!=0){for(col=1;col<=M->nu;col++)num[col]=0;for(t=1;t<=M->tu;t++)++num[M->data[t].j];cpot[1]=1;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].d=M->data[p].d;++cpot[col];}}printf("\n\n装之后的三元组为:\n\n");for(m=1;m<=T->tu;m++)printf("%3d%3d%3d\t",T->data[m].i,T->data[m].j,T->data[m].d);printf("\n");return T;}void print(TSMatrix *T,int x,int y){int m,n,p=1;int d;for(m=1;m<=x;m++){printf("\n");for(n=1;n<=y;n++){if(T->data[p].i==m&&T->data[p].j==n){d=T->data[p].d;p++;}elsed=0;printf("%6d",d);}}}void main(){TSMatrix *M;TSMatrix *T;M=(TSMatrix *)malloc(sizeof(TSMatrix));T=(TSMatrix *)malloc(sizeof(TSMatrix));printf("请输入行和列:\n");scanf("%d%d",&a,&b);M=creatarray(M);printf("请输入数组内容:\n");print(M,a,b);T=fasttrans(M,T);printf("数组内容为:\n");print(T,b,a);getchar();}五、实验测试及结果:请输入行和列:4 5请输入数组A:1 0 1 3 30 0 2 1 00 3 1 0 00 0 4 0 1原来三元组的表示为:1 1 1 1 3 1 1 4 3 1 5 323 22 4 13 2 3 3 3 14 3 4 45 1请输入数组内容:1 0 1 3 30 0 2 1 00 3 1 0 00 0 4 0 1六.总结与体会:稀疏矩阵的快速转置方法是预先确定好被转置矩阵的每一列的第一个非零元在转置后的目标矩阵三元组中的应有位置。
稀疏矩阵一次快速转置
西安邮电学院数据结构实验报告稀疏矩阵一次定位快速转置班级:班内序号:学生姓名:指导教师:时间:目录一、实验目的 (2)二、实验内容 (2)三、数据结构及算法思想 (2)1、对各个模块进行功能的描述 (2)2、模块之间关系及其相互调用的图示 (3)五、详细设计及运行结果 (3)1、设计源代码: (3)2、运行结果: (5)六、调试情况,设计技巧及体会 (5)一、实验目的1、进一步理解数组这个我们十分熟悉的结构,并了解在计数机内部是如何处理数组的。
2、熟悉并掌握特殊矩阵的定义和分类,并掌握它们的一种压缩存储方法。
3、理解并运用三元组表示方法压缩稀疏矩阵,通过“一次定位快速转置”法实现稀疏矩阵的转置。
二、实验内容运用“一次定位快速转置”实现对一个已知行、列及非零元素个数的稀疏矩阵的三元组表表示的转置。
三、数据结构及算法思想“一次定位快速转置”即将被转置的三元组表A的元素一次定位到三元组表B的正确位置上,具体做法为:用position[col]的初值表示三元组A中第col列中第一个非零元素的正确位置,当三元组A中第col列有一个元素加入到三元组表B时,则position[col]= position[col]+1,使position[col]始终指向三元组表A中第col列中下一个非零元素在三元素表B中的正确位置。
四、模块划分1、对各个模块进行功能的描述本次设计共分为三个模块,分别是输入模块、转置模块、显示模块。
各个模块功能如下表。
2、模块之间关系及其相互调用的图示图1五、详细设计及运行结果1、设计源代码:#include"stdio.h"#include"malloc.h"#define MAXSIZE 1000typedef struct{int row,col; int e;}Triple;typedef struct{Triple data[MAXSIZE+1]; int m,n,len;}TSMatrix;void FastTransposeTSMatrix(TSMatrix A,TSMatrix *B){int col,t,p,q;int num[MAXSIZE],position[MAXSIZE];B->len=A.len; B->n=A.m; B->m=A.n;if(B->len){for(col=1;col<=A.n;col++)num[col]=0;for(t=1;t<=A.len;t++)num[A.data[t].col]++;position[1]=1;for(col=2;col<=A.n;col++)position[col]=position[col-1]+num[col-1];for(p=1;p<=A.len;p++){col=A.data[p].col;q=position[col];B->data[q].row=A.data[p].col;B->data[q].col=A.data[p].row;B->data[q].e=A.data[p].e;position[col]++;}}}main(){TSMatrix M;TSMatrix *N=(TSMatrix *)malloc(sizeof(TSMatrix));int i;printf("请输入稀疏矩阵的行列数和非零元素的个数:\n");scanf("%d%d%d",&M.m,&M.n,&M.len);printf("请输入非零元素的位置下标和元素值:\n");for(i=1;i<=M.len;i++)scanf("%d%d%d",&M.data[i].row,&M.data[i].col,&M.data[i].e);printf("\n稀疏矩阵的三元组表示:");for(i=1;i<=M.len;i++)printf("\n%d %d %d",M.data[i].row,M.data[i].col,M.data[i].e);FastTransposeTSMatrix(M,N);printf("\n转置后的三元组:");for(i=1;i<=N->len;i++)printf("\n%d %d %d",N->data[i].row,N->data[i].col,N->data[i].e);getch();}2、运行结果:图 2六、调试情况,设计技巧及体会通过这次稀疏矩阵的“一次定位快速转置”设计的练习,我更充分掌握和理解了数组这一数据结构类型,并学习了特殊矩阵的压缩存储方法,体会到完一个程序,只是完成一个设计的一小部分,后期的调试和验证也是重要的一部分,这次设计完成代码后编译都没错,但运行结果却不正确,通过调试后才的找出错误,运行成功,但经过一些数据的验证却又发现问题,最后才发现是有个地方少输入一个“=”的原因,经过改正后结果就正确了,所以一个设计的完成是需要不断的改进、调试和验证的,其中耐心和细心更是不可缺少的。
稀疏矩阵快速转置算法的分析与优化
21 0 0年 8月
计算机 应 用与软 件
Co mpue p ia in n ot r trAp lc t sa d S fwae o
Vo. 7 No 8 12 .
Au .2 0 g 01
稀 疏 矩 阵快 速 转 置 算 法 的分 析 与优 化
t e e t o k n so r v d ag r h , o cu e t n o t s d ag r h t a o s se h d a tg flw rt o lxt n e it g h s w id f mp o e lo i m we c n l d oa p i e lo i m t s e s st e a v n a e o e me c mpe i i x si i t mi t h p o i y n f s t s o i o l o i m w i e u e h p c o lx t f h t l o i m sw l,a d i r a h st ep r o e o p i s g e it g fs a t r p s in ag rt h l r d c st e s a e c mp e i o a g rt a el n e c e h u p s fo t a n t h e y t a h t mii x si t n n a
n umb ro o ,t tlnu e frws oa mbe fc l mn n otlnu e flo z r lme so h pas arx. T a e ie he marx fs r ns o ro o u s a d t a mb ro n—e ee nt fte s r em t i o i he p p rgv st ti a tta p —
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
题目:假设稀疏矩阵A采用三元组表表示,编写程序实现该矩阵的快速转置要求:输入一个稀疏矩阵A,由程序将其转换成三元组表存储;转置后的三元组表,由程序将其转换成矩阵形式后输出。
一、需求分析1.用户可以根据自己的需求输入任意一个稀疏矩阵,通过程序将其转换成三元组存储方式;2.并且能够完成矩阵的转置功能,要求需要使用的方法是快速转置的方法。
3.最后要够显示原矩阵和转置后的矩阵让用户能进行比较。
4.程序执行的命令包括:(1)构造稀疏矩阵M (2)求转转矩阵T (3)显示(打印)矩阵二、概要设计⒈为实现上述算法,需要线性表的抽象数据类型:ADT SparseMatrix {数据对象:D={aij :|aij∈TermSet,i=1…m,m≥0,j=1…n,n≥0 m和n分别成为矩阵的行数和列数 }数据关系:R={Row,Col}Row ={<ai,j ,ai,j+1>|1≤i≤m,1≤j≤n-1 }Col ={<ai,j ,ai+1,j>|1≤i≤m-1,1≤j≤n }基本操作:CreateSMtrix(& M)操作结果:创建稀疏矩阵M。
DestroySMaix(&M)初始条件:稀疏矩阵M已存在。
操作结果:销毁稀疏矩阵M。
PrintSMatrix(L)初始条件:稀疏矩阵M已经存在。
操作结果:输出稀疏矩阵M。
CopySMatrix(M,&T)初始条件:稀疏矩阵M已经存在。
操作结果:由稀疏矩阵M复制得到T。
TransposeSMatrix(M,&T)初始条件:稀疏矩阵M已经存在。
操作结果:求稀疏矩阵M的转转矩阵T。
}ADT SparseMatrix2. 本程序有三个模块:⑴主程序模块main(){初始化;{接受命令;显示结果;}}⑵矩阵压缩存储单元模块:实现链表抽象数据类型操作,即函数的定义模块;三、详细设计⒈元素类型,结点类型typedef struct {int i,j;int e;}Triple;typedef struct{Triple data[MAXSIZE+1];int mu,nu,tu;} Tsmatrix;2.对抽象数据类型中的部分基本操作的伪码算法如下:Tsmatrix * creatarray(Tsmatrix *M){ int m,n,p=1;int c;printf("please input the array A:\n");for(m=1;m<=a;m++)for(n=1;n<=b;n++){ scanf("%d",&c);if(c!=0){ M->data[p].e=c;M->data[p].i=m;M->data[p].j=n;p++;}}M->tu=p; M->mu=a; M->nu=b;printf("yuan lai san yuan zu de biao shi wei :\n\n");for(m=1;m<=M->tu;m++)printf("%3d%3d%3d\t",M->data[m].i,M->data[m].j,M->data[m].e);printf("\n");return M;}/*三元组快速转置*/Tsmatrix * fasttrans(Tsmatrix *M,Tsmatrix *T){ int p,col,q,t,m;int num[100];int cpot[100];T->mu=M->nu; T->nu=M->mu; T->tu=M->tu;if(T->tu!=0){for(col=1;col<=M->nu;col++) num[col]=0;for(t=1;t<=M->tu;t++) ++num[M->data[t].j];cpot[1]=1;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];}}printf("\n\nzhuan zhi hou de san yuan zu biao shi wei :\n\n");for(m=1;m<=T->tu;m++)printf("%3d%3d%3d\t",T->data[m].i,T->data[m].j,T->data[m].e);printf("\n");return T;}/*输出三元组函数*/void print(Tsmatrix *T,int x,int y){ int m,n,p=1;int d;for(m=1;m<=x;m++){ printf("\n");for(n=1;n<=y;n++){ if(T->data[p].i==m&&T->data[p].j==n){ d=T->data[p].e;p++;}else d=0;printf("%6d",d);}}}}3.主函数和其他函数的伪码算法void main(){ Tsmatrix *M,*T;M=(Tsmatrix *)malloc(sizeof(Tsmatrix));T=(Tsmatrix *)malloc(sizeof(Tsmatrix));printf("please input array's row and col:\n");scanf("%d%d",&a,&b); /*输入行列数*/M=creatarray(M); /*创建稀疏矩阵*/printf("you had creat the array:\n");print(M,a,b); /*输出创建好的三元组*/T=fasttrans(M,T); /*将三元组转置*/printf("the trans array is:\n");print(T,b,a);getch();}4 函数调用关系四、调试分析⒈在定义变量的时候,我运用动了整型的全局变量a和b。
初步编程完后,编译出现如下的警告提示:可能在“a”定义以前使用了它在creatarray函数中。
通过检查发现我在creatarray函数中又定义了一个局部变量a,导致有如上的警告提示。
最后将局部变量a改为c就可以了。
⒉编译时的错误一大堆,但是致命的是在关键的函数快速转置有错误,在运行的结果中不是自己想要的结果。
在一一排除的情况下,数组转换三元组是正确的只是fasttrans函数算法有错,如出现下图的错误:最后发现原来的该函数的代码的算法少了几条语句。
3.因为要将稀疏矩阵M和稀疏矩阵T分别调用函数print,所以设计print函数的时候发现形参不仅仅要稀疏矩阵而且还应该有盖稀疏矩阵的行列数才能正确的输出稀疏矩阵,最后定义为print(Tsmatrix *T,int x,int y)才实现了输出。
4.算法的时空分析各操作的算法时间复杂度比较合理Creatarray,print为O(a*b)其中a和b分别表示稀疏矩阵的行列数fasttrans为O(tu) 其中tu表示稀疏矩阵中的非零个数5.本次实验采用数据抽象的程序设计方法,将程序化为三层次结构,设计时思路清晰,使调试也较顺利,各模块有较好的可重用性。
五、用户手册⒈本程序的运行环境为windows xp操作系统,并且在TC2.0中运行,执行文件为Exp2Prb5.c;⒉进入演示程序后,完成编译,再点击超级工具集里的中文DOS环境运行选项,进入DOS环境中,用户根据需求键入相应的数据,可以看到相应的结果。
六、测试结果所以在TC2.0中运行得到的结果如下图所示:(1)我输入的稀疏矩阵为:(2)回车显示的结果是:七、附录:源程序#include<stdio.h>#define MAXSIZE 100typedef struct {int i,j;int e;}Triple;typedef struct{Triple data[MAXSIZE+1];int mu,nu,tu;} Tsmatrix;int a,b; /*定义全局变量数组的行数a和列数b*/ /*用数组创建三元组*/Tsmatrix * creatarray(Tsmatrix *M){ int m,n,p=1;int c;printf("please input the array A:\n");for(m=1;m<=a;m++)for(n=1;n<=b;n++){ scanf("%d",&c);if(c!=0){ M->data[p].e=c;M->data[p].i=m;M->data[p].j=n;p++;}}M->tu=p; M->mu=a; M->nu=b;printf("yuan lai san yuan zu de biao shi wei :\n\n");for(m=1;m<=M->tu;m++)printf("%3d%3d%3d\t",M->data[m].i,M->data[m].j,M->data[m].e);printf("\n");return M;}/*三元组快速转置*/Tsmatrix * fasttrans(Tsmatrix *M,Tsmatrix *T){ int p,col,q,t,m;int num[100];int cpot[100];T->mu=M->nu; T->nu=M->mu; T->tu=M->tu;if(T->tu!=0){for(col=1;col<=M->nu;col++) num[col]=0;for(t=1;t<=M->tu;t++) ++num[M->data[t].j];cpot[1]=1;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];}}printf("\n\nzhuan zhi hou de san yuan zu biao shi wei :\n\n");for(m=1;m<=T->tu;m++)printf("%3d%3d%3d\t",T->data[m].i,T->data[m].j,T->data[m].e);printf("\n");return T;}/*输出三元组函数*/void print(Tsmatrix *T,int x,int y){ int m,n,p=1;int d;for(m=1;m<=x;m++){ printf("\n");for(n=1;n<=y;n++){ if(T->data[p].i==m&&T->data[p].j==n){ d=T->data[p].e;p++;}else d=0;printf("%6d",d);}}}void main(){ Tsmatrix *M,*T;M=(Tsmatrix *)malloc(sizeof(Tsmatrix));T=(Tsmatrix *)malloc(sizeof(Tsmatrix));printf("please input array's row and col:\n"); scanf("%d%d",&a,&b); /*输入行列数*/ M=creatarray(M);printf("you had creat the array:\n");print(M,a,b);T=fasttrans(M,T);printf("the trans array is:\n");print(T,b,a);getch();}。