稀疏矩阵的转置
稀疏矩阵的三元组顺序表存储表示及其转置算法
稀疏矩阵的三元组顺序表存储表示及其转置算法目录1. 引言1.1 背景和意义1.2 结构概述1.3 目的2. 稀疏矩阵的三元组顺序表存储表示2.1 稀疏矩阵的定义与特点2.2 三元组顺序表的数据结构和实现方式2.3 存储表示的优缺点分析3. 稀疏矩阵转置算法3.1 转置操作的意义与应用场景3.2 基于三元组顺序表的转置算法设计思路3.3 转置算法的具体实现步骤与复杂度分析4. 实验与结果分析4.1 实验设置和数据样本介绍4.2 转置算法在不同稀疏矩阵上的性能评估和结果比较4.3 分析结果及启示与讨论5. 结论与展望5.1 结论总结5.2 存在问题及后续工作展望1. 引言1.1 背景和意义稀疏矩阵是一种在实际问题中经常遇到的特殊矩阵结构,其绝大部分元素为零。
与稠密矩阵相比,稀疏矩阵的存储和计算效率更高。
稀疏矩阵可以应用于图像处理、网络分析、线性代数等领域。
三元组顺序表是一种存储稀疏矩阵的数据结构,通过记录非零元素的行索引、列索引和数值,有效地减少了存储空间。
同时,三元组顺序表也提供了便捷的转置操作方式。
因此,深入掌握稀疏矩阵的三元组顺序表存储表示及其转置算法对于提高稀疏矩阵相关问题的解决效率具有重要意义。
1.2 结构概述本文将从两个方面进行论述。
首先,介绍稀疏矩阵的定义与特点,以及三元组顺序表在存储表示中所采用的数据结构和实现方式。
其次,详细描述了基于三元组顺序表的稀疏矩阵转置算法的设计思路、具体实现步骤和复杂度分析。
1.3 目的本文旨在探究稀疏矩阵的三元组顺序表存储表示及其转置算法,在理论层面上深入分析其原理和优劣,并在实验中验证其性能表现。
通过本文的研究,我们希望能够提供一种高效、灵活且易于实现的方法来处理稀疏矩阵,并为进一步的相关应用提供有价值的启示和参考。
2. 稀疏矩阵的三元组顺序表存储表示2.1 稀疏矩阵的定义与特点稀疏矩阵是指在一个二维矩阵中,大部分元素都为0的情况下,只有少数非零元素的情况。
稀疏矩阵的表示和转置
实验2稀疏矩阵的表示和转置实验人:杜国胜学号:Xb14680103时间:11.91、实验目的1.掌握稀疏矩阵的三元组顺序表存储结构2.掌握稀疏矩阵的转置算法。
2、实验内容采用三元组表存储表示,求稀疏矩阵M的转置矩阵T。
(算法5.1)3、实验步骤:1.构建稀疏矩阵M。
2.求稀疏矩阵M的转置矩阵T。
3.输出稀疏矩阵M和稀疏矩阵T。
4、算法说明首先要创建稀疏矩阵和三元组顺序表,定义mu,mu,tu分别表示矩阵的行列数和非零元个数。
在进行稀疏矩阵的转置时要做到1.将矩阵的行列值相互交换2.将每个三元组的I,j相互调换3.重排三元组之间的次序5、测试结果6、分析讨论在此次程序中转置的方法称为快速转置,在转置前,应先求的M的每一列中非零元的个数,进而求得每一列的第一个非零元的位置7、附录:源代码#include<stdio.h>#define MAXSIZE 100typedef struct{int i,j;int e;}Triple;typedef struct{Triple data[MAXSIZE+1];int mu,nu,tu;}TSMatrix;//创建稀疏矩阵Mvoid CreateSMatrix (TSMatrix *M){int i,m,n,e,k;printf("输入矩阵M的行数、列数、非零元的个数(中间用逗号隔开):");scanf("%d,%d,%d",&(*M).mu,&(*M).nu,&(*M).tu);(*M).data[0].i=0;printf("\n");for(i=1;i<=(*M).tu;i++){do{printf("输入第%d个非零元素所在的行(1~%d)列(1~%d)值以及该数值:",i,(*M).mu,(*M).nu);scanf("%d,%d,%d",&m,&n,&e);k=0;if(m<1||m>(*M).mu||n<1||n>(*M).nu)k=1;if(m<(*M).data[i-1].i||m==(*M).data[i-1].i&&n<(*M).data[i-1].j)k=1;}while(k);(*M).data[i].i=m;(*M).data[i].j=n;(*M).data[i].e=e;}printf("\n");}//输出稀疏矩阵Mvoid PrintSMatrix(TSMatrix M){int i;printf("**************************************\n");for(i=1;i<=M.tu;i++)printf("%2d%4d%8d\n",M.data[i].i,M.data[i].j,M.data[i].e); printf("**************************************\n");printf("\n");}//求稀疏矩阵M的转置矩阵Tvoid TransposeSMatrix(TSMatrix M,TSMatrix *T){int p,q,col;(*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;}}}void print(TSMatrix A){int k=1,a,b;int M[MAXSIZE][MAXSIZE];printf("非零元素所对应的位置:\n");printf("**************************************\n"); for(a=0;a<A.mu;a++){for(b=0;b<A.nu;b++)M[a][b]=0;}while(k<=A.tu){M[A.data[k].i-1][A.data[k].j-1]=A.data[k].e;k++;}for(a=0;a<A.mu;a++){printf(" | ");for(b=0;b<A.nu;b++)printf("%d ",M[a][b]);printf(" | \n");}printf("**************************************\n"); printf("\n");}//主函数int main(){TSMatrix M,T;printf("创建矩阵M:");CreateSMatrix(&M);printf("矩阵M的三元组表为:\n");PrintSMatrix(M);print(M);TransposeSMatrix(M,&T);printf("稀疏矩阵M的转换矩阵T的三元组表为:\n");PrintSMatrix(T);print(T);printf("\n\n");getchar();return 0;}。
4.3.2 稀疏矩阵-两种转置算法
数组Content 数组的基本概念1特殊矩阵2稀疏矩阵3 A 稀疏矩阵的抽象数据类型B 稀疏矩阵的两种转置算法 C 稀疏矩阵的快速转置算法D 快速转置算法实例演示PART THREE B 稀疏矩阵的两种转置算法矩阵的转置a db ec f T=a b cd e f•在计算机图形学的领域中,矩阵可用来描述物体所有的点在一个线性空间里的坐标•在做图像处理或输出时,如果要对一个物体进行旋转/ 平移/ 缩放等操作,就要对描述这个物体的所有矩阵进行运算:➢在二维空间里矩阵的转置,就相当于得到关于某个点对称的二维图像➢在三维空间里矩阵的转置,同样是相当于得到关于某个点对称的三维立体Transpose•采用二维数组A存储一个普通m×n矩阵,假设将矩阵转置结果存储到n×m矩阵B中for(int i=0;i<m;i++)for(int j=0;j<n;j++)B[j][i]=A[i][j];上述程序段需要访问矩阵中的每一个元素,时间复杂度为O(m×n)步骤1:依次访问A的行三元组表中各个三元组<i, j, a>,交换元素行列号后依次ij保存到B的行三元组表中。
步骤2:将B的行三元组表中的行三元组按照行下标值从小到大重新排序。
•步骤1的时间复杂度为O(t)•步骤2是一个排序过程,采用不同排序算法的时间复杂度为O(t 2) 或O(tlog 2t)任何排序算法都可行吗?•步骤1:对A的行三元组表进行第1次扫描,找到列下标j = 0 的所有三元组<i, 0, a i0>,交换元素行列号后依次保存到B的行三元组表中。
•步骤2:对A的行三元组表进行第2次扫描,找到列下标j = 1 的所有三元组<i, 1, a i1>,交换元素行列号后依次保存到B的行三元组表中。
•……•步骤n:对A的行三元组表进行第n次扫描,找到列下标j = n-1 的所有三元组<i, n-1, a>,交换元素行列号后依次保存到B的行三元组表中。
稀疏矩阵存储和操作稀疏矩阵的数据结构与算法
稀疏矩阵存储和操作稀疏矩阵的数据结构与算法稀疏矩阵是指具有大量零元素和少量非零元素的矩阵。
在实际场景中,由于矩阵中大部分元素为零,传统的矩阵存储方式会造成大量的存储空间的浪费以及数据操作的低效性。
因此,为了节省存储空间和提高数据操作的效率,稀疏矩阵的存储和操作需要借助于特定的数据结构和算法。
一、稀疏矩阵存储的数据结构1.1. 压缩存储方法压缩存储方法是一种常用的稀疏矩阵存储方法。
常见的压缩存储方法有三种:行压缩法(CSR)、列压缩法(CSC)和十字链表法。
1.1.1. 行压缩法(CSR)行压缩法是通过两个数组来存储稀疏矩阵的非零元素。
第一个数组存储非零元素的值,第二个数组存储非零元素在矩阵中的位置信息。
1.1.2. 列压缩法(CSC)列压缩法与行压缩法相似,只是存储方式不同。
列压缩法是通过两个数组来存储稀疏矩阵的非零元素。
第一个数组存储非零元素的值,第二个数组存储非零元素在矩阵中的位置信息。
1.1.3. 十字链表法十字链表法是一种更加灵活的稀疏矩阵存储方法。
通过使用链表的方式,将非零元素存储在链表中,并且每个非零元素还具有行和列的指针,方便进行数据操作。
1.2. 坐标存储法坐标存储法是一种简单直观的稀疏矩阵存储方法。
每个非零元素包括行列坐标和元素值,通过三元组的方式进行存储。
二、稀疏矩阵的操作算法2.1. 矩阵转置矩阵转置是指将原矩阵的行变为列,列变为行的操作。
对于稀疏矩阵,常用的转置算法为快速转置算法。
该算法通过统计每列非零元素的个数,并根据列的非零元素个数确定每个非零元素转置后的位置。
2.2. 矩阵相加矩阵相加是指将两个矩阵对应位置上的元素相加得到一个新的矩阵。
对于稀疏矩阵的相加,可以遍历两个矩阵的非零元素,对相同位置上的元素进行相加。
2.3. 矩阵相乘矩阵相乘是指将两个矩阵相乘得到一个新的矩阵。
对于稀疏矩阵的相乘,常用的算法为稀疏矩阵乘法算法。
该算法通过遍历两个矩阵的非零元素,按照矩阵乘法的规则计算得到新矩阵的非零元素。
稀疏矩阵的存储和快速转置实验报告
福建工程学院课程设计课程:数据结构题目:稀疏矩阵的快速转置专业:运算机类班级:座号:姓名:2021年6月25日实验题目:稀疏矩阵的快速转置一、要解决的问题利用三元组表存储稀疏矩阵,利用快速转置算法进行转置,并输出转置之前和以后的三元组表和矩阵。
二、算法大体思想描述:由于稀疏矩阵的非零元素较少,零元素较多,因此只需存储其非零元素。
因此能够成立一个三元组表,别离保存稀疏矩阵的非零元素的行号、列号和元素值。
对稀疏矩阵进行快速转置是能够引入两个向量num[n+1],cpot[n+1],别离标记矩阵中第col列的非零元素个数和第一个非零元素在转置后的矩阵的位置;再扫描三元组表,找到非零元素,直接对其在转置后的矩阵所在的位置上进行修改,以节省时刻。
三、详细设计⒈元素类型,结点类型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、模块结构及功能}四、源程序清单:#include<>#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();}五、测试数据及测试结果:(1)我输入的稀疏矩阵为:(2)回车显示的结果是:六、课程设计总结及心得体会:通过本次课程设计,我对有关稀疏矩阵及其三元组表的知识做了温习和巩固。
三元组表示稀疏矩阵的转置(一般算法和快速算法)
一、设计要求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稀疏矩阵的存储不宜⽤⼆维数组存储每个元素,那样的话会浪费很多的存储空间。
数据结构——稀疏矩阵运算器
数据结构——稀疏矩阵运算器数据结构——稀疏矩阵运算器1、简介1.1 背景稀疏矩阵是一种特殊的矩阵,其中包含大量的零元素。
与密集矩阵相比,稀疏矩阵在存储和计算上具有更高的效率。
稀疏矩阵运算器是一种特定的工具,用于执行稀疏矩阵的各种运算,如加法、减法、乘法等。
1.2 目的2、稀疏矩阵的定义与表示2.1 稀疏矩阵的定义稀疏矩阵是指在矩阵中只有部分元素非零的矩阵。
通常,如果矩阵中超过一定比例的元素为零,则可以将其称为稀疏矩阵。
2.2 稀疏矩阵的表示稀疏矩阵可以使用多种表示方式,如数组、链表、三元组等。
每种表示方式都有各自的特点和适用范围。
3、稀疏矩阵运算的基本概念3.1 稀疏矩阵加法稀疏矩阵加法是指对两个稀疏矩阵进行元素级别的相加操作。
该操作要求两个矩阵具有相同的维度。
3.2 稀疏矩阵减法稀疏矩阵减法是指对两个稀疏矩阵进行元素级别的相减操作。
该操作要求两个矩阵具有相同的维度。
3.3 稀疏矩阵乘法稀疏矩阵乘法是指对两个稀疏矩阵进行矩阵乘法运算。
该操作要求第一个矩阵的列数等于第二个矩阵的行数。
4、稀疏矩阵运算器的实现4.1 基本功能稀疏矩阵运算器应具备稀疏矩阵加法、减法和乘法的基本功能。
用户可以输入矩阵的维度和元素值,然后执行相应的运算。
4.2 稀疏矩阵的表示与存储稀疏矩阵的表示与存储是稀疏矩阵运算器的关键部分。
可以使用多种数据结构来表示和存储稀疏矩阵,如三元组、链表等。
4.3 稀疏矩阵运算的算法实现稀疏矩阵运算的算法实现是稀疏矩阵运算器的核心部分。
可以使用各种算法来实现稀疏矩阵的加法、减法和乘法运算。
5、附加功能与性能优化5.1 稀疏矩阵转置稀疏矩阵转置是指将稀疏矩阵的行与列进行交换。
该操作可以提高计算效率,并减少存储空间的使用。
5.2 稀疏矩阵的压缩与解压缩稀疏矩阵的压缩与解压缩是指将稀疏矩阵的存储空间进行优化,从而减少存储空间的使用。
5.3 算法的优化与性能测试稀疏矩阵运算器的性能优化是一个重要的方向。
稀疏矩阵的转置
b. mu=6 b. nu=5 b. tu=7
2 转置算法的实现
SPMatrix* TransM1(SPMatrix *a){
SPMatrix *b; b=(SPMatrix*)malloc(sizeof(SPMatrix));
转
b->mu=a -> nu; b-> nu=a -> mu; b -> tu=a -> tu;
b .data 1 1 1 15
A
a .data 2 1 4 22
b.data 2 1 5 91
的 转 置
a .data 3 a .data 4
1 6 -15 2 2 11
b .data 3 2 2 11
求解 b .data 4 3 2 3
矩
a .data 5 2 3 3
阵
B
a .data 6 3 4 6
转置算法的设计
寻找 j=col 的a.data [ p]
a . data p i j v
b . data p i j v
a .data 1 1 1 15
b .data 1 1 1 15
a .data 2 1 4 22 Col=5 b.data 2 5 1 91
a .data 3 a .data 4
1 6 -15 2 2 11
a . data p i j v
b . data p i j v
a .data 1 a .data 2 a .data 3 a .data 4
1 1 15 1 4 22 1 6 -15 2 2 11
b .data 1 1 1 15 Col=1 b.data 2 1 5 91
b .data 3
对稀疏矩阵结构的操作
对稀疏矩阵结构的操作稀疏矩阵是一种特殊的矩阵结构,其大部分元素为0,只有少部分非零元素。
由于稀疏矩阵的特殊性,对其进行操作时需要采用特定的方法和算法。
本文将介绍几种常见的对稀疏矩阵进行操作的方法。
一、稀疏矩阵的存储方式稀疏矩阵的存储方式有多种,常见的有三元组表示法和压缩存储方式。
三元组表示法是将非零元素的行、列和值分别存储在三个数组中,这种存储方式简单直观,但是对于大规模稀疏矩阵来说,空间占用较大。
压缩存储方式则是将稀疏矩阵按行或按列进行压缩存储,只存储非零元素的位置和值,可以大大减小空间占用。
二、稀疏矩阵的加法和减法对于稀疏矩阵的加法和减法,可以采用三元组表示法或压缩存储方式。
首先需要将两个矩阵转换为相同的存储方式,然后按照矩阵的行列进行遍历,将对应位置的元素进行加法或减法操作。
在遍历过程中,需要注意处理非零元素的情况,可以采用稀疏矩阵的存储结构进行判断和处理。
三、稀疏矩阵的乘法稀疏矩阵的乘法是一种复杂的运算,涉及到矩阵的行列遍历和乘法操作。
对于两个稀疏矩阵的乘法,可以采用三元组表示法或压缩存储方式。
首先需要将两个矩阵转换为相同的存储方式,然后按照矩阵的行列进行遍历,对于每个非零元素,需要找到对应位置的元素进行乘法操作,并将结果累加。
在遍历过程中,可以采用稀疏矩阵的存储结构进行优化,减少不必要的运算。
四、稀疏矩阵的转置稀疏矩阵的转置是将矩阵的行和列进行互换,对于稀疏矩阵,可以采用三元组表示法或压缩存储方式进行转置。
对于三元组表示法,只需要将行和列进行互换即可;对于压缩存储方式,只需要将行和列的索引进行互换,并按照转置后的行列顺序重新排列非零元素。
五、稀疏矩阵的求逆稀疏矩阵的求逆是一种复杂的运算,需要借助于线性代数的知识和算法。
对于稀疏矩阵的求逆,可以采用LU分解、LDU分解或Cholesky分解等方法。
这些方法可以将稀疏矩阵分解为三个矩阵的乘积,然后再求解逆矩阵。
在求解过程中,需要注意处理稀疏矩阵的特殊结构,以提高求解的效率。
4.3.3 稀疏矩阵-快速转置算法
数组Content数组的基本概念1特殊矩阵2稀疏矩阵3A 稀疏矩阵的抽象数据类型B 稀疏矩阵的两种转置算法C 稀疏矩阵的快速转置算法D 快速转置算法实例演示PART THREE C 稀疏矩阵的快速转置算法O(列数+非零元个数)观察规律•转置前A中列号为j的第一个元素,变成转置后B中行号为j的第一个元素•B中行号为j的第一个元素在B的下标等于A中前j列非零元个数num数组求解•数组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]++;j012345num221200计算数组num的时间复杂度为O(n+t)•数组k中k[j] 统计稀疏矩阵A中列号从0到j-1列(前j列)的非零元个数总和•k[j]表示A中j列第一个非零元在转置稀疏矩阵B 的行三元组表中的下标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];j 012345num221200k024577计算数组k的时间复杂度为O(n)快速转置算法for(int i=0;i<t;i++){int index =k[A.table[i].col]++;B.table[index].col =A.table[i].row;B.table[index].row =A.table[i].col;B.table[index].value =A.table[i].value;}•k[j]的值表示稀疏矩阵列号为j 的列中第一个非零元在转置矩阵中的存储位置•k[j]每被访问一次执行一次自加操作,暗示该列中下一个非零元的存储位置。
稀疏矩阵的建立与转置(优选.)
实验2 稀疏矩阵的建立与转置一、实验目的掌握特殊矩阵的存储和操作算法。
二、实验内容及问题描述实现用三元组保存稀疏矩阵并实现矩阵转置的算法。
三、实验步骤1. 定义稀疏矩阵的三元组形式的存储结构。
2. 实现三元组矩阵的传统转置算法。
3. 实现三元组矩阵的快速转置算法。
4. 输入矩阵非零元素,测试自己完成的算法。
四、程序流程图五、概要设计矩阵是很多的科学与工程计算中研究的数学对象。
在此,我们感兴趣的是,从数学结构这门学科着眼,如何存储矩阵的元从而使矩阵的各种运算有效的进行。
本来,用二维数组存储矩阵,在逻辑上意义是很明确的,也很容易理解,操作也很容易和方便。
但是在数值分析中经常出现一些阶数很高的矩阵,同时,在矩阵中又有很多值相同或者都为零的元素,可以对这种矩阵进行压缩存储:对多个值相同的元素只分配一个存储空间;对零元素不分配空间。
稀疏矩阵的定义是一个模糊的定义:即非零元个数较零元个数较少的矩阵。
例如下图所示的矩阵为一个稀疏矩阵。
为了实现稀疏矩阵的这种存储结构,引入三元组这种数据结构。
三元组的线性表顺存储形式如下图:六、详细设计sanyuanzu.h 头文件#define max 100typedef struct{int row,col;int e;}Triple;//定义三元组typedef struct{Triple data[max];int mu,nu,tu;}TSMatrix;///*定义三元组的稀疏矩阵*/void creat( TSMatrix &M) ;void fasttrans(TSMatrix A,TSMatrix &B);void printfx(TSMatrix x);sanyuanzu.cpp 文件#include<stdio.h>#include"sanyuanzu.h"/*建立三元组的稀疏矩阵*/void creat( TSMatrix &M){printf("请输入稀疏矩阵的行数:");scanf("%d",&M.mu);printf("请输入稀疏矩阵的列数:");scanf("%d",&M.nu);printf("请输入矩阵中非零元素的个数:");scanf("%d",&M.tu);int i;printf("请输入这%d 个元素的行号和列号及其元素的值:/n",M.tu);for(i = 1; i <= M.tu;i++)scanf("%d %d %d",&M.data[i].row,&M.data[i].col,&M.data[i].e);}/*实现三元组的矩阵转置的函数*/void fasttrans(TSMatrix A,TSMatrix &B){int col,cpot[max],num[max],t,p,q;/*初始化矩阵B*/B.mu=A.nu;B.nu=A.mu;B.tu=A.tu;if(B.tu){for(col=1;col<=A.nu;++col)num[col]=0;/*初始化每一列非零元的个数*/for(t=1;t<=A.tu;++t)++num[A.data[t].col];/*计算每一列非零元的个数*/cpot[1]=1;for(col=2;col<=A.nu;++col)cpot[col]=cpot[col-1]+num[col-1];//计算矩阵A 每一列第一个非零元在B.data 中的位置/*实现对A 中的每一个非零元进行转置*/for(p=1;p<=A.tu;++p){col=A.data[p].col;q=cpot[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;++cpot[col];}}}/*稀疏矩阵的输出*/void printfx(TSMatrix x){int i,j;for(j=1;j<=x.tu;j++){for(i=1;i<=x.mu;i++)if(x.data[j].row==i)printf("%d %d %d/n",x.data[j].row,x.data[j].col,x.data[j].e );}}main.cpp 文件#include<stdio.h>#include'"sanyuanzu.cpp"//主函数int main(void){TSMatrix t,s;creat(t);printf("你所输入的稀疏矩阵为:/n");printfx(t);fasttrans(t,s);printf("转置后的稀疏矩阵为:/n");printfx(s);return 0;}}七、调试报告八、分析与遇到的问题(1)创建稀疏矩阵时,不懂如何用三元组表示元素的输出;(2)需要注意矩阵运算中的特殊状况,稀疏矩阵相加时,忘记对应元素相加为0时,在稀疏矩阵中不表示;(3)矩阵相加时,第一个矩阵的行列数要和第二个矩阵的行列数相等;(4)输出矩阵时,输出界面不整齐。
稀疏矩阵的转置课程设计
稀疏矩阵的转置课程设计一、课程目标知识目标:1. 理解稀疏矩阵的概念及特点;2. 掌握稀疏矩阵转置的数学定义和性质;3. 学会使用压缩存储方法对稀疏矩阵进行转置操作;4. 能够运用转置后的稀疏矩阵解决实际问题。
技能目标:1. 培养学生运用数学软件或编程语言处理稀疏矩阵转置问题的能力;2. 提高学生分析问题、解决问题的能力;3. 培养学生的逻辑思维和抽象思维能力。
情感态度价值观目标:1. 培养学生对线性代数学科的兴趣和热情;2. 培养学生严谨、求实的科学态度;3. 增强学生的团队合作意识和协作能力;4. 引导学生认识到数学在自然科学和工程技术领域的重要作用。
本课程针对高年级学生,结合稀疏矩阵的转置这一章节内容,注重理论与实践相结合。
在教学过程中,充分考虑学生的认知特点,采用启发式教学,引导学生自主探究和合作学习。
通过本课程的学习,使学生不仅掌握稀疏矩阵转置的相关知识,而且提高解决实际问题的能力,培养良好的情感态度价值观。
二、教学内容1. 稀疏矩阵的基本概念与性质- 稀疏矩阵的定义- 稀疏矩阵的存储方法:压缩存储- 稀疏矩阵的运算规则2. 稀疏矩阵转置的数学定义- 转置矩阵的定义及性质- 稀疏矩阵转置的数学表达式3. 稀疏矩阵转置的算法实现- 顺序转置法- 分块转置法- 矩阵压缩存储下的转置方法4. 稀疏矩阵转置的应用实例- 图像处理中的稀疏矩阵转置- 工程问题中的稀疏矩阵转置应用5. 教学案例分析及讨论- 结合实际案例,分析稀疏矩阵转置的必要性- 讨论不同转置算法的优缺点及适用场景本教学内容依据课程目标,结合教材章节,按照由浅入深、循序渐进的原则进行安排。
在教学过程中,注重理论与实践相结合,强调算法实现与应用。
通过本章节的学习,使学生全面掌握稀疏矩阵转置的相关知识,提高解决实际问题的能力。
三、教学方法1. 讲授法- 对于稀疏矩阵的基本概念、性质及转置的数学定义等理论知识,采用讲授法进行教学,使学生系统掌握相关知识。
Chapter52稀疏矩阵转置
二、行逻辑联接的顺序表
三元组顺序表又称有序的双下标 法,它的特点是,非零元在表中按行 序有序存储,因此便于进行依行顺序 处理的矩阵运算。然而,若需随机存 取某一行中的非零元,则需从头开始 进行查找。
}// TransposeSMatrix
首先应该确定转置矩阵中 每一行的第一个非零元在三元组中的位置。
1 2 15 1 5 -5 2 2 -7 3 1 36 3 4 28
col 1 2 3 4 5 Num[pos] 1 2 0 1 1 Cpot[col] 1 2 4 4 5
cpot[1] = 1; for (col=2; col<=M.nu; ++col)
其时间复杂度为: O(mu×nu)
实现三元组表存储的稀疏矩阵的转置运算
mu nu tu 678 ijv 1 2 12 139 3 1 -3 3 6 14 4 3 24 5 2 18 6 1 15 6 4 -7
mu nu tu 76 8 ij v 2 1 12 31 9 1 3 -3 6 3 14 3 4 24 2 5 18 1 6 15 4 6 -7
其时间复杂度为: O(m1×n2×n1)
• for (i=1; i<=m1; ++i) • for (j=1; j<=n2; ++j) { • Q[i][j]=0; • for(k(0---n1-1) • Q[i][j]+=M[i][k]*N[k][j]
数据结构稀疏矩阵转置,加法
数据结构稀疏矩阵转置,加法《数据结构》实验报告◎实验题⽬:稀疏矩阵的转置、加法(⾏逻辑链接表)◎实验⽬的:学习使⽤三元组顺序表表⽰稀疏矩阵,并进⾏简单的运算◎实验内容:以三元组表表⽰稀疏矩阵,并进⾏稀疏矩阵的转置和加法运算。
⼀、需求分析该程序⽬的是为了⽤三元组表实现稀疏矩阵的转置和加法运算。
1、输⼊时都是以三元组表的形式输⼊;2、输出时包含两种输出形式:运算后得到的三元组表和运算后得到的矩阵;3、测试数据:(1)转置运算时输⼊三元组表:1 2 121 3 93 1 -33 6 144 3 245 2 186 1 156 4 -7得到转置后的三元组表:1 3 -31 6 152 1 122 5 183 1 93 4 244 6 -76 3 14(2)进⾏加法运算时先输⼊矩阵A(以三元组表形式):1 1 12 2 22 3 43 1 -4输⼊矩阵B(以三元组表形式):1 3 -22 3 -53 1 83 2 -6A与B的和矩阵以矩阵形式输出为:1 0 -20 2 -14 -6 0(⼆) 概要设计为了实现上述操作⾸先要定义三元组表,稀疏矩阵:typedef struct{int i,j;int e;}Triple;//三元组typedef struct{Triple data[MAXSIZE+1];int mu,nu,tu;}Matrix;//稀疏矩阵1.基本操作void CreatMatrix(Matrix *m)操作结果:创建⼀个稀疏矩阵。
void PrintMatrix(Matrix m)初始条件:矩阵m已存在。
操作结果:将矩阵m以矩阵的形式输出。
void FastTransposeMatrix(Matrix a,Matrix *b)初始条件:稀疏矩阵a已存在;操作结果:将矩阵a进⾏快速转置后存⼊b中。
void AddMatrix(Matrix a,Matrix b,Matrix *c)初始条件:稀疏矩阵a和b都已存在;操作结果:将矩阵a和b的和矩阵存⼊c中。
实验四稀疏矩阵三元组下转置
实验四、稀疏矩阵三元组下转置一、实验内容将稀疏矩阵中的每个非零元素aij表示为(i, j, v),即(行号,列号,非零元素值).称为三元组表示法。
用结构类型来描述三元组。
将稀疏矩阵的非零元素对应的三元组所构成的集合,按行优先的顺序排列成一个线性表。
在稀疏矩阵用三元组顺序表存储结构下,实现稀疏矩阵转置,得到其转置矩阵的三元组顺序表存储表示。
要求:1)采用转置算法Ⅰ:直接取,顺序存2)采用转置算法Ⅱ:顺序取,直接存。
要使用两个辅助一维数组,分别先计算出原矩阵每一列的非零元个数以及每一列的第一个非零元在转置矩阵的三元组顺序表中的存储位置。
二、实验目的1. 掌握稀疏矩阵的三元组顺序表存储结构;2. 掌握稀疏矩阵转置算法Ⅰ;3. 掌握稀疏矩阵转置算法Ⅱ三、实验代码//文件:SparseMatrix.htemplate <class T>struct element{int row, col; //行数、列数T item; //元素值};const int MaxTerm=100;template <class T>class SparseMatrix{ public:SparseMatrix(){};SparseMatrix(int intmu,int intnu,int inttu,element<T> datatemp[]);//有参构造函数,初始化稀疏矩阵~SparseMatrix(){}; //析构函数,释放存储空间element<T> GetMatrix(int intnumber);//输出下标对应的数组元素void Prt();//显示三元组顺序表void Trans1(SparseMatrix<T> &B);//直接取、顺序存的矩阵转置算法void Trans2(SparseMatrix<T> A, SparseMatrix<T> &B);//顺序取、直接存的矩阵转置算法private:element<T> data[MaxTerm]; //矩阵非零元素int mu, nu, tu; //行数、列数、非零元个数};// 文件:SparseMatrix.cpp#include "SparseMatrix.h" //引用三元组顺序表的头文件#include <string> //引用string库函数的头文件using namespace std;//指出后续的所有的程序语句都在名字空间std内/*前置条件:三元组顺序表不存在输入:三元组顺序表的行数(intmu)、列数(intnu)、非零元个数(inttu)、初始三元组(datatemp[])功能:三元组顺序表的初始化输出:无后置条件:建立一个三元组顺序表*/template <class T>SparseMatrix<T>::SparseMatrix(int intmu,int intnu,int inttu,element<T> datatemp[]){if (inttu >MaxTerm ) throw "构造函数的初始化参数不正确";mu = intmu;nu = intnu;tu = inttu;for(int i=0;i<inttu;i++){data[i] = datatemp[i];}}/*前置条件:三元组顺序表已存在输入:下标(intnumber)功能:读取这组下标对应的数组元素输出:对应元素后置条件:三元组顺序表不变*/template <class T>element<T> SparseMatrix<T>::GetMatrix(int intnumber){if(intnumber>=tu || intnumber < 0) throw "输入位置不正确";return data[i];}/*前置条件:无输入:无功能:显示三元组顺序表输出:无后置条件:建立一个三元组顺序表*/template <class T>void SparseMatrix<T>::Prt(){for(int i=0;i<tu;i++){cout<<data[i].row<<" "<<data[i].col<<" "<<data[i].item<<"\n";}}/*前置条件:无输入:待转置的源三元组顺序表(A)和目标三元组顺序表(B)的引用功能:对三元组顺序表进行转置输出:无后置条件:三元组顺序表A的转置结果放在了B中*/template <class T>void SparseMatrix<T>::Trans1(SparseMatrix<T> &B){int pb,pa;B.mu=this->nu; B.nu=this->mu; B.tu=this->tu;//设置行数、列数、非零元素个数 if (B.tu>0) //有非零元素则转换{pb = 0;for (int col=0; col<this->nu; col++) //依次考察每一列 for (pa=0; pa<this->tu; pa++) //在A中扫描整个三元组表if (this->data[pa].col==col ) //处理col列元素{B.data[pb].row= this->data[pa].col ;B.data[pb].col= this->data[pa].row ;B.data[pb].item= this->data[pa].item;pb++;}}}/*前置条件:无输入:待转置的源三元组顺序表(A)和目标三元组顺序表(B)的引用功能:对三元组顺序表进行转置输出:无后置条件:三元组顺序表A的转置结果放在了B中*/template <class T>void SparseMatrix<T>::Trans2(SparseMatrix<T> A, SparseMatrix<T> &B){int i,j,k,num[MaxTerm],cpot[MaxTerm];B.mu=A.nu; B.nu=A.mu; B.tu=A.tu;//设置行数、列数、元素个数if (B.tu>0) //有非零元素则转换{for (i=0; i<A.nu; i++) num[i]=0; //A中每一列非零元素的个数初始化为0 for (i=0; i<A.tu; i++)//求矩阵A中每一列非零元素的个数{ j= A.data[i].col; //取三元组的列号num[j]++;}cpot[0]=0; //A中第0列第一个非零元素在B中的位置为0for (i=1; i<A.nu; i++) //求A中每一列第一个非零元素在B中的下标cpot[i]= cpot[i-1]+num[i-1];for (i=0; i<A.tu; i++)//扫描三元组表A{j=A.data[i].col; //当前三元组的列号k=cpot[j]; //当前三元组在B中的下标B.data[k].row= A.data[i].col ;B.data[k].col= A.data[i].row ;B.data[k].item= A.data[i].item;cpot[j]++; //预置同一列的下一个三元组的下标}}}//文件:SparseMatrixMain.cpp#include <iostream> //引用输入输出流库函数的头文件#include "SparseMatrix.cpp" ////引用广义表的成员函数文件#include <string> //引用string库函数的头文件using namespace std; //指出后续的所有的程序语句都在名字空间std内int main(){try{//建立一个element<int>类型的数组(A)element<int> A[7]={{0,0,15},{0,3,22},{0,5,-15},{1,1,11},{1,2,3},{2,3,6},{4,0,91}};SparseMatrix<int> sparsematrixB;//构造三元组顺序表来存储转置后的三元组顺序表 SparseMatrix<int> sparsematrixA(5,6,7,A);//构造三元组顺序表cout<<"原三元组顺序表如下:"<<"\n";sparsematrixA.Prt();//显示三元组顺序表sparsematrixA.Trans1(sparsematrixB);cout<<"使用直接取、顺序存转置算法转置后的三元组顺序表如下:"<<"\n";sparsematrixB.Prt();//显示三元组顺序表sparsematrixA.Trans2(sparsematrixA,sparsematrixB);cout<<"使用顺序取、直接存转置算法转置后的三元组顺序表如下:"<<"\n";sparsematrixB.Prt();//显示三元组顺序表}catch(char* e){ cout<<e; }return 0;}四、调试和运行结果在完成算法的程序实现后,用任意的一组数据来加以测试运行,对运行结果加以分析,检查运行结果是否正确。
数据结构实验之稀疏矩阵的转置
实验六:稀疏矩阵的转置[实验题目]改编教材中一维数组类,增加成员函数Array1D<T> & operator +(Array1D<T>& c2);,可以做求和运算,并在主程序里输入完两个长度相同的一维数组之后,调用这个成员函数求和。
完善教材中稀疏矩阵,调试转置运算,并编写出两个重定义的流操作运算,并自行编写主程序验证输出两个三元组,稀疏矩阵转置是否成功。
[概要分析]对一个稀疏矩阵,写成行三元组形式,对行三元组扫描一次即可定位,而关键是找到每列(0,1,…,n-1)首个非0元素的位置,在新的三元组转置,记在k数组中。
分别建立SeqTriple.cpp、SeqTriple.h、TsteSeqTripleMain.cpp。
[详细设计]1.类的结构2.核心代码(1)转置思路:快速转置算法使用n个指针k[i](0<=i<n)(n是矩阵的列数),指向稀疏矩阵M中i列的第一个非零元素在转置后的三元组B中的存放位置。
有了k[i],只要对三元组扫描一次即可定位。
关键在于找到每列首个非零元素的位置k[0]=0;k[i]=k[i-1]+num[i-1];具体代码:void SeqTriple<T>::Transpose(SeqTriple<T>& B)const{ //将this 转置赋给Bint *num=new int[n]; int *k=new int[n]; //为num和k分配空间B.m=n; B.n=m; B.t=t;if (t>0){for (int i=0; i<n; i++) num[i]=0; //初始化numfor (i=0; i<t; i++) num[trip[i].col]++; //计算numk[0]=0;for(i=1; i<n; i++) k[i]=k[i-1]+num[i-1]; //计算kfor(i=0; i<t; i++){ //扫描this对象的三元组表int j=k[trip[i].col]++; //求this对象的第i项在B中的位置jB.trip[j].row=trip[i].col; //将this对象的第i项转置到B的位置jB.trip[j].col=trip[i].row;B.trip[j].value=trip[i].value;}}delete [] num;delete [] k;}(2)整体赋值思路:先将本类对象所占空间清空,再按赋值对象(即参数对象)规格重新申请空间,最后循环拷贝每个元素。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#define MaxSize 100
typedef int ElemType;
//三元组
typedef struct
{
int m,n; //m为行数,n为列数
ElemType e; //非零元素的值
}Triple;
//稀疏矩阵
typedef struct
{
Triple data[MaxSize+1];
int mu,nu,tu; //总行数、总列数、总非零元素个数
}TSMatrix;
//int p;
//菜单
void MENU()
{
printf("\n");
printf(" 【稀疏矩阵的转置】\n");
printf("……………………………………\n");
printf("…1、初始化…\n");
printf("……\n");
printf("…2、显示…\n");
printf("……\n");
printf("…3、转置…\n");
printf("……\n");
printf("…4、退出…\n");
printf("……………………………………\n");
printf("\n");
printf("请选择菜单项:");
}
//初始化
void BUILD(TSMatrix&T)
{
T.tu=0;
printf("请输入矩阵的总行数和总列数,按回车键结束:\n");
printf("(如3行5列请输入3,5)\n");
scanf("%d,%d",&T.mu,&T.nu);
printf("请输入非零元素的行数、列数和值,按ctrl+z与回车键结束:\n");
printf("(如行3列5值1请输入3,5,1,表示第3行第5列的元素值为1)\n");
while(scanf("%d,%d,%d",
&T.data[T.tu].m,&T.data[T.tu].n,&T.data[T.tu].e)!=EOF) {
T.tu++;
}
printf("非零元素有%d个\n",T.tu);
printf("矩阵已成功建立!\n");
}
//显示
void SHOW(TSMatrix&T)
{
int bufTu = 0;
int i,j;
for(i=1;i<=T.mu;i++)
{
for(j=1;j<=T.nu;j++)
{
if(j==T.data[bufTu].n&&i==T.data[bufTu].m)
{
printf("%d ",T.data[bufTu].e);
bufTu++;
}
else
{
printf("0 ");
}
}
printf("\n");
}
getch();
}
//转置
int TRANSFER(TSMatrix &T,TSMatrix &M)
{
int p,q,col;
M.mu=T.nu;
M.nu=T.mu;
M.tu=T.tu;
if(M.tu)
{
q=0;
for(col=1;col<=T.nu;col++)
{
for(p=0;p<=T.tu;p++)
{
if(T.data[p].n==col)
{
M.data[q].m=T.data[p].n;
M.data[q].n=T.data[p].m;
M.data[q].e=T.data[p].e;
q++;
}
}
}
}
return 0;
}
//主函数
int main()
{
TSMatrix T,M;
int i,j,s;
char r;
while(1)
{
system("cls");
MENU();
r=getch();
system("cls");
switch(r)
{
case '1':
BUILD(T);
s=1;
system("pause");
break;
case '2':
if(s==1)
{
printf("当前的矩阵为:\n");
SHOW(T);
printf("\n");
system("pause");
}
else
{
printf("请先初始化!\n");
system("pause");
}
break;
case '3':
if(s==1)
{
printf("原来的矩阵为:\n");
SHOW(T);
TRANSFER(T,M);
printf("\n");
printf("现在的矩阵为:\n");
SHOW(M);
system("pause");
}
else
{
printf("请先初始化!\n");
system("pause");
}
break;
case '4':
exit(1);
break;
default:
printf("您输入的菜单项不存在,请重新输入!");
getch();
break;
}
}
}。