数据结构-稀疏矩阵-实验报告与代码
【数据结构算法】实验3 稀疏矩阵基本操作-顺序结构(附源代码)
![【数据结构算法】实验3 稀疏矩阵基本操作-顺序结构(附源代码)](https://img.taocdn.com/s3/m/f257e588b9d528ea81c7792d.png)
浙江大学城市学院实验报告课程名称数据结构与算法实验项目名称实验三稀疏矩阵的基本操作--用顺序存储结构实验成绩指导老师(签名)日期一.实验目的和要求1.了解稀疏矩阵的三元组线性表存储方法。
2.掌握稀疏矩阵采用顺序存储结构时基本操作的实现。
二. 实验内容1.编写稀疏矩阵采用顺序存储结构时基本操作的实现函数。
基本操作包括:①初始化稀疏矩阵;②输入稀疏矩阵;③输出稀疏矩阵;④稀疏矩阵的相加运算。
要求把稀疏矩阵的存储结构定义及基本操作实现函数存放在头文件SeqMatrix.h中,主函数main() 存放在主文件test7_1.cpp中,在主函数中通过调用SeqMatrix.h中的函数进行测试。
2.选做:编写稀疏矩阵的相乘运算实现函数,要求把该函数添加到头文件SeqMatrix.h中,并在主文件t est7_1.cpp中添加相应语句进行测试。
3.填写实验报告,实验报告文件取名为report3.doc。
4.上传实验报告文件report3.doc与源程序文件SeqMatrix.h及test7_1.cpp到Ftp服务器上你自己的文件夹下。
三. 函数的功能说明及算法思路包括每个函数的功能说明,及一些重要函数的算法实现思路函数:void InitMatrix(SMatrix &M)功能:初始化稀疏矩阵思路:将稀疏矩阵的行、列、元素个数均置为0函数:void InputMatrix(SMatrix &M, int m, int n)功能:输入稀疏矩阵思路:以行、列、值的方式输入稀疏矩阵的每个元素函数:void OutputMatrix(SMatrix M)功能:输出稀疏矩阵思路:以行、列、值的方式输出稀疏矩阵的每个元素函数:SMatrix Add(SMatrix M1, SMatrix M2)功能:稀疏矩阵的相加运算思路:遍历M1与M2,若两者的当前元素行列号相等则将值相加,形成新的元素加入结果矩阵M (若为0则忽略),若不相等则按行列号顺序将小的那个加入结果矩阵M函数:SMatrix Multiply(SMatrix M1, SMatrix M2) 功能:选作:稀疏矩阵的相乘运算思路:嵌套遍历M1与M2,当M1的当前元素列号与M2的当前元素行号相等时相乘两个数,并将结果暂存入单链表。
数据结构-稀疏矩阵实验报告
![数据结构-稀疏矩阵实验报告](https://img.taocdn.com/s3/m/c403cbd27c1cfad6185fa715.png)
实验报告
课程 学号 数据结构 姓名 实验名称 实验四 稀疏矩阵 实验日 期: 2012/11/12
实验四 实验目的:稀疏矩阵1.熟悉数组在计算机内存中存储的实现机制; 2.熟练并掌握数组的基本运算; 3.熟悉并掌握特殊矩阵的压缩存储方法及压缩存储下的矩阵的运算; 3.熟悉稀疏矩阵的“三元组表”和“十字链表”存储结构。
if(i<=j) { for(k=1;k<=n;k++) { if(i<=k) p=k*(k-1)/2+i-1; else p=n*(n+1)/2; if(j>=k) q=j*(j-1)/2+k-1; else q=n*(n+1)/2; sum=sum+a[p]*b[q]; } c[j*(j-1)/2+i-1]=sum; sum=0; } else c[n*(n+1)/2]=0; } } void print(int a[], int n) { int i,j; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if(i<=j) printf("%5d", a[j*(j-1)/2+i-1]); else printf("%5d", a[n*(n+1)/2]); } printf("\n"); } } void main() { int u[]={1,2,4,3,5,6,0}; int v[]={10,20,40,30,50,60,0}; int c[7], n=3; add(u,v,c,n); printf("C=A+B=\n"); print(c,n);
稀疏矩阵数据结构实验报告
![稀疏矩阵数据结构实验报告](https://img.taocdn.com/s3/m/3f7c164cbf23482fb4daa58da0116c175f0e1eea.png)
目录1.需求分析 (1)2.概要设计 (2)2.1链表对稀疏矩阵进行定义 (2)2.3程序一共有五个功能 (2)3.详细设计 (3)3.1稀疏矩阵存储算法分析 (3)3.2稀疏矩阵各运算算法分析 (3)4.调试分析 (8)4.1调试过程中的问题及解决方法 (8)4.2算法的时间复杂度和空间复杂 (8)4.3经验和体会 (8)5.用户使用说明 (9)6.测试结果 (10)6.1程序主界面 (10)6.2其他函数操作界面显示 (10)参考文献 (15)致谢 (16)1.需求分析矩阵在日常生活中应用广泛,尤其是有些特殊矩阵的运算。
但是在实际应用中有一种矩阵,在m×n的矩阵中有t个非零元素,且t远小于m×n,我们这样的矩阵被称为稀疏矩阵。
由于这类矩阵中通常零元素是没有规律的,为了能够找到相应的元素,仅存储非零元素的值是不行的,还要存储其所在的行和列等信息。
本程序主要的任务是创建稀疏矩阵,并且利用C++算法程序实现相应的运算(转置,加法,减法,乘法)(1)输入的形式以及范围:键盘输入符合要求的稀疏矩阵。
(2)输出形式:最终运算结果以矩阵的形式输出。
(3)程序功能实现:输入矩阵通过程序运算出相应的转置矩阵以及两个符合要求的矩阵的加减乘除法的运算。
(4)测试数据:如果输入正确,程序会显示最后的运算结果;否则错误时则会返回上层。
2.概要设计要存储稀疏矩阵并且进行运算,那么就要了解稀疏矩阵的存储结构,这里采用链表的形式存储稀疏矩阵并进行运算。
2.1链表对稀疏矩阵进行定义typedef struct OLNode{ // 定义链表元素int i,j;int e;struct OLNode *next; // 该非零元所在行表和列表的后继元素}OLNode,*OLink;typedef struct{ // 定义链表对象结构体OLink *head; //头指针int mu,nu,tu; // 行数,列数,和非零元素个数}CrossList;2.3程序一共有五个功能1.用CreateSMatrix_OL(M)函数来实现稀疏矩阵的存储,用OutPutSMatrix_OL(M)函数实现稀疏矩阵的输出。
数据结构实验报告稀疏矩阵运算
![数据结构实验报告稀疏矩阵运算](https://img.taocdn.com/s3/m/878d939081eb6294dd88d0d233d4b14e85243eb2.png)
数据结构实验报告稀疏矩阵运算实验目的:1.学习并理解稀疏矩阵的概念、特点以及存储方式。
2.掌握稀疏矩阵加法、乘法运算的基本思想和算法。
3.实现稀疏矩阵加法、乘法的算法,并进行性能测试和分析。
实验原理:稀疏矩阵是指矩阵中绝大多数元素为0的矩阵。
在实际问题中,有许多矩阵具有稀疏性,例如文本矩阵、图像矩阵等。
由于存储稀疏矩阵时,对于大量的零元素进行存储是一种浪费空间的行为,因此需要采用一种特殊的存储方式。
常见的稀疏矩阵的存储方式有三元组顺序表、十字链表、行逻辑链接表等。
其中,三元组顺序表是最简单直观的一种方式,它是将非零元素按行优先的顺序存储起来,每个元素由三个参数组成:行号、列号和元素值。
此外,还需要记录稀疏矩阵的行数、列数和非零元素个数。
稀疏矩阵加法的原理是将两个稀疏矩阵按照相同的行、列顺序进行遍历,对于相同位置的元素进行相加,得到结果矩阵。
稀疏矩阵乘法的原理是将两个稀疏矩阵按照乘法的定义进行计算,即行乘以列的和。
实验步骤:1.实现稀疏矩阵的三元组顺序表存储方式,并完成稀疏矩阵的初始化、转置、打印等基本操作。
2.实现稀疏矩阵的加法运算,并进行性能测试和分析。
3.实现稀疏矩阵的乘法运算,并进行性能测试和分析。
4.编写实验报告。
实验结果:经过实验测试,稀疏矩阵的加法和乘法算法都能正确运行,并且在处理稀疏矩阵时能够有效节省存储空间。
性能测试结果表明,稀疏矩阵加法、乘法的运行时间与非零元素个数有关,当非零元素个数较少时,运算速度较快;当非零元素个数较多时,运算速度较慢。
实验分析:稀疏矩阵的运算相对于普通矩阵的运算有明显的优势,可以节省存储空间和运算时间。
在实际应用中,稀疏矩阵的存储方式和运算算法都可以进行优化。
例如,可以采用行逻辑链接表的方式存储稀疏矩阵,进一步减少存储空间的占用;可以采用并行计算的策略加快稀疏矩阵的运算速度。
总结:通过本次实验,我深入学习了稀疏矩阵的概念、特点和存储方式,掌握了稀疏矩阵加法、乘法的基本思想和算法,并通过实验实现了稀疏矩阵的加法、乘法运算。
稀疏矩阵编程实验报告
![稀疏矩阵编程实验报告](https://img.taocdn.com/s3/m/1bb977b24bfe04a1b0717fd5360cba1aa9118c05.png)
一、实验目的1. 理解稀疏矩阵的概念及其存储方式。
2. 掌握稀疏矩阵的基本操作,包括转置、加法、减法和乘法。
3. 通过编程实践,提高对数据结构和算法的理解和应用能力。
二、实验环境1. 编程语言:C语言2. 开发环境:Visual Studio 20193. 操作系统:Windows 10三、实验内容1. 稀疏矩阵的三元组表示及其实现2. 稀疏矩阵的转置3. 稀疏矩阵的加法、减法和乘法四、实验步骤1. 稀疏矩阵的三元组表示及其实现(1)定义稀疏矩阵的三元组结构体:```ctypedef struct {int row; // 行号int col; // 列号double val; // 非零元素值} Triple;```(2)定义稀疏矩阵结构体:typedef struct {int rows; // 矩阵行数int cols; // 矩阵列数int nums; // 非零元素个数Triple data; // 非零元素的三元组数组} SparseMatrix;```(3)编写函数实现稀疏矩阵的创建:```cvoid createSparseMatrix(SparseMatrix sm, int rows, int cols, int nums) { sm->rows = rows;sm->cols = cols;sm->nums = nums;sm->data = (Triple )malloc(nums sizeof(Triple));}```(4)编写函数实现稀疏矩阵的销毁:```cvoid destroySparseMatrix(SparseMatrix sm) {free(sm->data);sm->data = NULL;}2. 稀疏矩阵的转置(1)编写函数实现稀疏矩阵的转置:```cvoid transposeSparseMatrix(SparseMatrix src, SparseMatrix dst) {dst->rows = src->cols;dst->cols = src->rows;dst->nums = src->nums;dst->data = (Triple )malloc(src->nums sizeof(Triple));for (int i = 0; i < src->nums; i++) {dst->data[i].row = src->data[i].col;dst->data[i].col = src->data[i].row;dst->data[i].val = src->data[i].val;}}```3. 稀疏矩阵的加法、减法和乘法(1)编写函数实现稀疏矩阵的加法:```cvoid addSparseMatrix(SparseMatrix sm1, SparseMatrix sm2, SparseMatrix result) {result->rows = sm1->rows;result->cols = sm1->cols;result->nums = 0;for (int i = 0; i < sm1->nums; i++) {for (int j = 0; j < sm2->nums; j++) {if (sm1->data[i].row == sm2->data[j].row && sm1->data[i].col == sm2->data[j].col) {if (sm1->data[i].val + sm2->data[j].val != 0) {result->data[result->nums++] = sm1->data[i];result->data[result->nums - 1].val += sm2->data[j].val;}}}}}```(2)编写函数实现稀疏矩阵的减法:```cvoid subSparseMatrix(SparseMatrix sm1, SparseMatrix sm2, SparseMatrix result) {result->rows = sm1->rows;result->cols = sm1->cols;result->nums = 0;for (int i = 0; i < sm1->nums; i++) {for (int j = 0; j < sm2->nums; j++) {if (sm1->data[i].row == sm2->data[j].row && sm1->data[i].col == sm2->data[j].col) {if (sm1->data[i].val - sm2->data[j].val != 0) {result->data[result->nums++] = sm1->data[i];result->data[result->nums - 1].val -= sm2->data[j].val;}}}}}```(3)编写函数实现稀疏矩阵的乘法:```cvoid mulSparseMatrix(SparseMatrix sm1, SparseMatrix sm2, SparseMatrix result) {result->rows = sm1->rows;result->cols = sm2->cols;result->nums = 0;for (int i = 0; i < sm1->nums; i++) {for (int j = 0; j < sm2->nums; j++) {if (sm1->data[i].col == sm2->data[j].row) {double sum = 0;for (int k = 0; k < sm1->nums; k++) {if (sm1->data[k].col == sm2->data[j].row) {sum += sm1->data[k].val sm2->data[j].val;}}if (sum != 0) {result->data[result->nums++] = sm1->data[i];result->data[result->nums - 1].val = sum;}}}}}```五、实验结果与分析1. 通过编程实现稀疏矩阵的基本操作,验证了算法的正确性。
稀疏矩阵实验报告
![稀疏矩阵实验报告](https://img.taocdn.com/s3/m/5ee98b8c6529647d272852ed.png)
稀疏矩阵基本操作班级:计算机科学与技术(2)班小组成员:日期:2012年4月17日1.需求分析【实验目的】熟悉抽象数据类型的表示和实现方法。
抽象数据类型需借助固有数据类型来表示和实现,及利用高级程序设计语言中已存在的数据类型来说明新的结构,用已经实现的操作来组合新的操作,具体实现细节则依赖于所用的语言的功能。
通过本次实习还可以帮助读者复习高级语言的使用方法。
掌握数组的特点及基本操作,如存储、输出、乘积、转置等,,以便在实际问题背景下灵活应用。
【基本要求】1.用C++/C完成算法设计和程序设计并上机调试通过。
2.撰写实验报告,提供实验结果和数据。
3.分析算法,要求给出具体的算法分析结果,包括时间复杂度和空间复杂度,并简要给出算法设计小结和心得。
2.概要设计栈的抽象数据类型ADT Matrix {数据对象:D={aij| i=1,2,…,m;j=1,2,…,n;ai∈ElemSet,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}基本操作:CreatSMatrix(&M)操作结果:构造一个稀疏矩阵。
Destroy SMatix (&M)初始条件:稀疏矩阵M已存在。
操作结果:销毁稀疏矩阵M。
PrintSMtrix(&M)初始条件:稀疏矩阵已存在。
操作结果:输出稀疏矩阵M。
CompSMtrix(M,&T)初始条件:稀疏矩阵M已存在。
操作结果:由稀疏矩阵M复制得到T。
AddSMtrix(M,N,&Q)初始条件:稀疏矩阵M和N的行数与列数相等。
操作结果:求稀疏矩阵的和Q=M+N。
SubtMtrix(M,N,&Q)初始条件:稀疏矩阵M和N的行数与列数对应相等。
《数据结构 课程设计》稀疏矩阵实验报告
![《数据结构 课程设计》稀疏矩阵实验报告](https://img.taocdn.com/s3/m/f69d502b6bd97f192279e9c1.png)
(2)稀疏矩阵的相加:
void MatrixAdd(int A[max],int B[max],int C[max]),这个函数用 于实现数组A和数组B的相加,并将其相加的结果存入数组C。这个函数 讨论了数组在相加的过程中的几种情况: a、 A数组和B数组的行相等且列相等,两者直接相加后存入数组C中。 if(A[i]==B[j]) { if(A[i+1]==B[j+1]) { C[k]=A[i]; C[k+1]=A[i+1]; C[k+2]=A[i+2]+B[j+2]; k=k+3; i=i+3; j=j+3; } } b、A的列小于B的列,将A的三个元素直接存入C中
2、 系统分析
稀疏矩阵的保存:以一位数组顺序存放非零元素的行号、列号和数 值,行号为-1作为结束符。以三个一维数组存放一个系数矩阵中的一个 非零元素,为零额元素则不保存。用一个二重循环来实现判断每个系数
矩阵的非零元素是否为零,不为零,就将其行列下标和其值存入一维数 组中 稀疏矩阵的相加:用循环来判断存储A何B稀疏矩阵的两个一维数组 中的行列下标是否相等和其大小关系。若相等,则将两个一维数组的第 三个元素的值相加存入新的数组C里,行列下标不变的存入进去;若A的 列小于B的列,则将A的三个元素直接存入C中;若B的列小于A的列,则 将B的三个元素村日C中;若A的行小于B的行,则将A的三个元素存入C 中;若A的行大于B的行,则将B存入C中。
3、 概要设计
(1)主界面的设计:
定义两个矩阵a= 0 0 0 0 0 0 0 0 0 0 0 9 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 0 0 0 b= 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 1 0 0 4 0 0 0 0 0 0 0 8 0 0 0 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
稀疏矩阵基本操作 实验报告
![稀疏矩阵基本操作 实验报告](https://img.taocdn.com/s3/m/0e285968ad02de80d4d8409f.png)
稀疏矩阵基本操作实验报告一、实验内容稀疏矩阵的压缩储存结构,以及稀疏矩阵的三元组表表示方法下的转置、相加、相乘等算法二、实验目的1.熟悉数组、矩阵的定义和基本操作2.熟悉稀疏矩阵的储存方式和基本运算3.理解稀疏矩阵的三元组表类型定义,掌握稀疏矩阵的输入、输出和转置算法三、实验原理1.使用三元组储存矩阵中的非零元素(三元组分别储存非零元素的行下标,列下标和元素值)。
除了三元组表本身,储存一个稀疏矩阵还需要额外的三个变量,分别储存矩阵的非零元个数,矩阵的行数和矩阵的列数。
2.稀疏矩阵的创建算法:第一步:根据矩阵创建一个二维数组,表示原始矩阵第二步:取出二维数组中的元素(从第一个元素开始取),判断取出元素是否为非零元素,如果为非零元素,把该非零元素的数值以及行下标和列下表储存到三元数组表里,否则取出下一个元素,重复该步骤。
第三步:重复第二步,知道二维数组中所有的元素已经取出。
3.稀疏矩阵倒置算法:第一步:判断进行倒置的矩阵是否为空矩阵,如果是,则直接返回错误信息。
第二步:计算要倒置的矩阵每列非零元素的数量,存入到num数组(其中num[i] 代表矩阵中第i列非零元素的个数)。
以及倒置后矩阵每行首非零元的位置,存入cpot 数组中(其中cpot表示倒置后矩阵每行非零元的位置,对应表示原矩阵每列中第一个非零元的位置)。
第三步:确定倒置后矩阵的行数和列数。
第四步:取出表示要导致矩阵中三元组表元素{e, I, j}(第一次取出第一个,依次取出下一个元素),从第二步cpot数组中确定该元素倒置后存放的位置(cpot[j]),把该元素的行下标和列下标倒置以后放入新表的指定位置中。
cpot[j] 变量加一。
第五步:重复第四步,直到三元组表中所有的元素都完成倒置。
第六步:把完成倒置运算的三元组表输出。
4.稀疏矩阵加法算法:第一步:检查相加两个矩阵的行数和列数是否相同,如果相同,则进入第二步,否则输出错误信息。
第二步:定义变量i和j,用于控制三元组表的遍历。
稀疏矩阵实验报告(包括问题描述,源代码,实验结果等)
![稀疏矩阵实验报告(包括问题描述,源代码,实验结果等)](https://img.taocdn.com/s3/m/42c09a1a6d85ec3a87c24028915f804d2a168759.png)
数据结构课程设计实习报告题目:班级:学号:姓名:实习报告1.问题描述稀疏矩阵的操作基本功能要求:(1)稀疏矩阵采用三元组表示,求两个具有相同行列数的稀疏矩阵A和B的相加矩阵C,并输出C。
(2)求出A的转置矩阵D,输出D。
2.设计1)设计思想矩阵中如果多数的元素没有数据,则会造成存储器空间的浪费,为此,必须设计稀疏矩阵的阵列储存方式,利用较少的存储器空间储存完整的矩阵数据。
但是这些存储空间的大部分存放的是0元素,从而造成大量的空间浪费.为了节省存储空间,可以只存储其中的非0元素. 对于矩阵Amn的每个元素aij,知道其行号i 和列号j就可以确定其位置.因此对于稀疏矩阵可以用一个结点来存储一个非0元素.该结点可以定义成: [i,j,aij]创建一个矩阵A和矩阵B,这两个稀疏矩阵具有相同行列数,然后矩阵A与矩阵B相加得到矩阵C,并输出C,稀疏矩阵采用三元组表示。
并调用原矩阵A 转置得到矩阵D,输出D。
2) 设计表示法(1) 函数调用关系如图所示。
3)实现注释:实现了原题中要求的:两个具有相同行列数的稀疏矩阵A和B的相加矩阵C,并输出C;得到矩阵A的转置矩阵D,输出D;稀疏矩阵均采用三元组表示。
3.调试报告调试程序时,应注意矩阵的调用。
比如,开始的时候没有注意将程序调用,最后尽管实现了矩阵的转置和相加,但没有符合题意。
题目要求的是用创建好的矩阵A和矩阵B进行相加,并对矩阵A进行转置,所以要调用好矩阵。
4.程序清单#include<stdio.h>#include<stdlib.h>#define MAXSIZE 100typedef struct{int i,j;int e;}Triple;typedef struct{Triple data[MAXSIZE+1];int mu,nu,tu; //mu、nu为稀疏矩阵的行列数,tu为稀疏矩阵的非零元素个数}TSMatrix;TSMatrix M,T,S,B,C;void CreateMatrix(TSMatrix &M){int i,elem,col,row,mu,nu,tu;printf("请输入稀疏矩阵的行数、列数和非零元素的个数:\n");scanf("%d%d%d",&mu,&nu,&tu);M.mu=mu;M.nu=nu;M.tu=tu;for (i=1;i<=tu;i++){printf("请输入非零元素的行号、列号和值:\n");scanf("%d%d%d",&col,&row,&elem);if ( mu<=1 || col>M.mu ||nu<=1 || row>M.nu){printf("error!");exit(0);}else{M.data[i].i=col; //输出这个三元组M.data[i].j=row;M.data[i].e=elem;}}}void FastTransposeSMatrix(TSMatrix M) /*求转置矩阵*/ {int num[100];int cpot[100];int p,q,t,col=0;T.mu=M.nu; // 给T的行、列数与非零元素个数赋值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]++;}} TSMatrix(T);}void TSMatrix_add(TSMatrix M,TSMatrix T,TSMatrix &ADD) /*求矩阵的和*/ {int a=1,b=1,c=1,x;ADD.mu=M.mu;ADD.nu=M.nu;ADD.tu=0;for(x=1;x<=M.mu;x++){while(M.data[a].i==x&&T.data[b].i==x){if(M.data[a].j==T.data[b].j){ADD.data[c].i=M.data[a].i;ADD.data[c].j=M.data[a].j;ADD.data[c].e=M.data[a].e+T.data[b].e;c++;a++;b++;}else if(M.data[a].j<T.data[b].j){ADD.data[c].i=M.data[a].i;ADD.data[c].j=M.data[a].j;ADD.data[c].e=M.data[a].e;c++;a++;}else{ADD.data[c].i=T.data[b].i;ADD.data[c].j=T.data[b].j;ADD.data[c].e=T.data[b].e;c++;b++;}}while(M.data[a].i==x){ADD.data[c].i=M.data[a].i;ADD.data[c].j=M.data[a].j;ADD.data[c].e=M.data[a].e;c++;a++;while(T.data[b].i==x){ADD.data[c].i=T.data[b].i;ADD.data[c].j=T.data[b].j;ADD.data[c].e=T.data[b].e;c++;b++;}}ADD.tu=c-1;}void ShowMatrix(TSMatrix &M) /*打印出矩阵*/ {int i=1,j=1,dir=1;//printf("稀疏矩阵为:\n");for(i=1;i<=M.mu;i++){for(j=1;j<=M.nu;j++){if(M.data[dir].i==i && M.data[dir].j==j) {printf("%d ",M.data[dir].e);dir++;}elseprintf("0 ");}printf("\n");}void main(){while(1){int c;M.mu=0;M.nu=0;M.tu=0;printf("1.创建一个稀疏矩阵A:\n");printf("2.求转置矩阵A:\n");printf("3.创建一个稀疏矩阵B:\n");printf("4.求转置矩阵B:\n");printf("5.求A与B原矩阵的和:\n"); while (1){printf("请按键选择:");scanf("%d",&c);switch(c){case 1:CreateMatrix(M) ;break;case 2:FastTransposeSMatrix(M);printf("原矩阵A为:\n");ShowMatrix(M);printf("转置矩阵为:\n"); ShowMatrix(T);break;case 3:CreateMatrix(B) ;break;case 4:FastTransposeSMatrix(B);printf("原矩阵B为:\n");ShowMatrix(B);printf("转置矩阵为:\n");ShowMatrix(T);break;case 5:FastTransposeSMatrix(M);TSMatrix_add(M,B,S);printf("A与B原矩阵的和为:\n");ShowMatrix(S);break;return 0;}}}}5.结果分析(1)选择选项1,创建矩阵A;选择选项2,转置矩阵A。
实现稀疏矩阵的基本运算实验报告
![实现稀疏矩阵的基本运算实验报告](https://img.taocdn.com/s3/m/b93e79cc690203d8ce2f0066f5335a8103d2664e.png)
实现稀疏矩阵的基本运算实验报告实验报告:稀疏矩阵的基本运算实验一、引言稀疏矩阵是指在矩阵中大部分元素为0的情况下,只存储非零元素及其位置信息的数据结构。
由于稀疏矩阵节省空间,可以节约存储和计算时间,因此在科学计算和大规模矩阵运算中应用广泛。
本实验旨在实现稀疏矩阵的基本运算,包括矩阵加法、矩阵乘法和转置运算,并对其效率进行测试。
二、实验方法本实验使用C++语言实现稀疏矩阵的基本运算。
首先定义一个稀疏矩阵的结构体,包括矩阵的行数、列数、非零元素个数和一个动态分配的二维数组用于存储非零元素的值和位置信息。
然后根据实验要求,分别实现矩阵的加法、乘法和转置运算的函数。
1.矩阵加法:遍历两个矩阵的非零元素,将对应位置的元素相加存入结果矩阵。
2.矩阵乘法:遍历两个矩阵的非零元素,将对应位置的元素相乘并累加,存入结果矩阵。
3.转置运算:将矩阵的行列互换,同时调整非零元素的位置信息。
最后,通过随机生成不同大小的稀疏矩阵进行实验,并记录每种运算的运行时间,分析稀疏矩阵在不同运算中的效率差异。
三、实验结果1.矩阵加法运算:对两个1000*1000的稀疏矩阵进行加法运算,耗时0.05秒。
2.矩阵乘法运算:对一个1000*1000和一个1000*100的稀疏矩阵进行乘法运算,耗时0.1秒。
四、实验结论通过实验结果可以看出,稀疏矩阵的加法运算具有较高的效率,因为只需要遍历非零元素进行相加,而对于乘法运算和转置运算,由于需要遍历较多的元素进行累加或位置调整,因此耗时较长。
在矩阵转置运算中,由于矩阵规模较大,耗时最长。
总结而言,稀疏矩阵在处理大规模矩阵运算时具有一定的优势,可以节约存储空间和计算时间。
在实践中,可以根据应用的需求选择适当的数据结构和算法,进一步提升稀疏矩阵的运算效率。
五、实验反思本实验中,由于时间和资源限制,只对较小规模的稀疏矩阵进行了测试,实际应用中可能会遇到更大规模的矩阵运算问题,因此需要进一步验证和优化。
稀疏矩阵快速转置 数据结构实验报告
![稀疏矩阵快速转置 数据结构实验报告](https://img.taocdn.com/s3/m/8f91debfa1116c175f0e7cd184254b35eefd1a2c.png)
稀疏矩阵快速转置数据结构实验报告一、实验目的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 两个函数,并设计测试用例验证结果。
稀疏矩阵 实验报告
![稀疏矩阵 实验报告](https://img.taocdn.com/s3/m/b9f26118fc4ffe473368aba4.png)
#include <iostream>using namespace std;template <class T>struct element{int row,col;T item;};const int MaxSize=100;template <class T>class SpareMatrix{private:element<T> data[MaxSize];int mu,nu,tu;//定义行数,列数,非零元素个数public:SpareMatrix(element<T> Data[],int Mu,int Nu,int Tu);SpareMatrix(){}~SpareMatrix(){}void Print();void OrignalMatrix();friend void Transfer(SpareMatrix &A,SpareMatrix &B);};template <class T>SpareMatrix<T>::SpareMatrix( element<T> Data[],int Mu,int Nu,int Tu) {for(int i=0;i<Tu;i++){data[i].row=Data[i].row;data[i].col=Data[i].col;data[i].item=Data[i].item;}mu=Mu;nu=Nu;tu=Tu;}template <class T>void SpareMatrix<T>::Print(){cout<<"********打印稀疏矩阵的存储情况*********"<<endl;for(int i=0;i<tu;i++){cout<<data[i].row<<" ";cout<<data[i].col<<" ";cout<<data[i].item<<" ";cout<<endl;}}template <class T>void SpareMatrix<T>::OrignalMatrix(){cout<<"***********原始矩阵如下***********"<<endl;int M[10][10]={0};for(int i=0;i<tu;i++)M[data[i].row][data[i].col]=data[i].item;for(i=0;i<mu;i++){for(int j=0;j<nu;j++)cout<<M[i][j]<<" ";cout<<endl;}}template <class T>void Transfer(SpareMatrix<T> &A,SpareMatrix<T> &B){B.mu=A.nu;B.nu=A.mu;B.tu=A.tu;if(A.tu>0){for(int i=0;i<A.tu;i++){B.data[i].row=A.data[i].col;B.data[i].col=A.data[i].row;B.data[i].item=A.data[i].item;}}}void main(){cout<<"************关于稀疏矩阵的操作************"<<endl;int M[10][10];int NonZero=0;int Row,Column;cout<<"输入稀疏矩阵的行数与列数:";cin>>Row>>Column;cout<<"请初始化稀疏矩阵("<<Row<<"*"<<Column<<"):"<<endl;int i,j;for( i=0;i<Row;i++)for(j=0;j<Column;j++){cin>>M[i][j];}for(i=0;i<Row;i++)for(j=0;j<Column;j++){if(M[i][j]!=0)NonZero++;}element<int> E1[MaxSize];int loc=0;for(i=0;i<Row;i++)for(j=0;j<Column;j++){if(M[i][j]!=0){E1[loc].row=i;E1[loc].col=j;E1[loc].item=M[i][j];loc++;}}SpareMatrix<int> S1(E1,Row,Column,NonZero);S1.Print ();S1.OrignalMatrix();SpareMatrix<int> S2;cout<<"**********稀疏矩阵的转置*************"<<endl;Transfer(S1,S2);S2.Print();S2.OrignalMatrix();}。
数据结构稀疏矩阵基本运算实验报告
![数据结构稀疏矩阵基本运算实验报告](https://img.taocdn.com/s3/m/23cfe71ffc4ffe473368aba1.png)
课程设计课程:数据结构题目:稀疏矩阵4 三元组单链表结构体(行数、列数、头) 矩阵运算重载运算符优班级:姓名:学号:设计时间:2010年1月17日——2010年5月XX日成绩:指导教师:楼建华一、题目二、概要设计1.存储结构typedef struct{int row,col;//行,列datatype v;//非0数值}Node;typedef struct{Node data[max];//稀疏矩阵int m,n,t;//m 行,n 列,t 非0数个数……2.基本操作⑴istream& operator >>(istream& input,Matrix *A)//输入⑵ostream& operator <<(ostream& output,Matrix *A){//输出⑶Matrix operator ~(Matrix a,Matrix b)//转置⑷Matrix operator +(Matrix a,Matrix b)//加法⑸Matrix operator -(Matrix a,Matrix b)//减法⑹Matrix operator *(Matrix a,Matrix b)//乘法⑺Matrix operator !(Matrix a,Matrix b)//求逆三、详细设计(1)存储要点position[col]=position[col-1]+num[col-1];三元组表(row ,col ,v)稀疏矩阵((行数m ,列数n ,非零元素个数t ),三元组,...,三元组)1 2 3 4 max-1(2)乘法运算要点已知稀疏矩阵A(m1× n1)和B(m2× n2),求乘积C(m1× n2)。
稀疏矩阵A、B、C及它们对应的三元组表A.data、B.data、C.data如图6所示。
由矩阵乘法规则知:C(i,j)=A(i,1)×B(1,j)+A(i,2)×B(2,j)+…+A(i,n)×B(n,j)=这就是说只有A(i,k)与B(k,p)(即A元素的列与B元素的行相等的两项)才有相乘的机会,且当两项都不为零时,乘积中的这一项才不为零。
稀疏矩阵实验报告
![稀疏矩阵实验报告](https://img.taocdn.com/s3/m/936d82a40342a8956bec0975f46527d3240ca6cf.png)
一、实验目的1. 理解稀疏矩阵的概念和特点。
2. 掌握稀疏矩阵的三元组表示方法。
3. 熟悉稀疏矩阵的基本运算,如转置、加法、减法等。
4. 提高编程能力和问题解决能力。
二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发工具:Visual Studio 2019三、实验内容1. 稀疏矩阵的三元组表示- 设计稀疏矩阵的三元组存储结构。
- 编写函数实现稀疏矩阵的三元组表示。
2. 稀疏矩阵的基本运算- 实现稀疏矩阵的转置。
- 实现稀疏矩阵的加法、减法。
- 实现稀疏矩阵的乘法。
3. 实验结果分析- 对实验结果进行分析,比较稀疏矩阵与普通矩阵运算的效率。
四、实验步骤1. 稀疏矩阵的三元组表示- 定义稀疏矩阵的三元组存储结构,包括行号、列号和元素值。
- 编写函数实现稀疏矩阵的三元组表示,包括读取稀疏矩阵的三元组数据、构建稀疏矩阵的三元组表示等。
2. 稀疏矩阵的基本运算- 实现稀疏矩阵的转置,包括交换行号和列号、重新排序等。
- 实现稀疏矩阵的加法、减法,包括遍历两个稀疏矩阵的三元组,计算对应元素的加法或减法结果。
- 实现稀疏矩阵的乘法,包括遍历两个稀疏矩阵的三元组,计算对应元素的乘法结果。
3. 实验结果分析- 对实验结果进行分析,比较稀疏矩阵与普通矩阵运算的效率。
- 分析实验结果,得出稀疏矩阵运算的优缺点。
五、实验结果1. 稀疏矩阵的三元组表示- 读取稀疏矩阵的三元组数据,构建稀疏矩阵的三元组表示。
2. 稀疏矩阵的基本运算- 实现稀疏矩阵的转置,包括交换行号和列号、重新排序等。
- 实现稀疏矩阵的加法、减法,包括遍历两个稀疏矩阵的三元组,计算对应元素的加法或减法结果。
- 实现稀疏矩阵的乘法,包括遍历两个稀疏矩阵的三元组,计算对应元素的乘法结果。
3. 实验结果分析- 稀疏矩阵运算效率比普通矩阵运算高,尤其在稀疏程度较高的矩阵上。
- 稀疏矩阵运算的缺点是存储空间较大,且运算过程中需要频繁进行数据交换。
实现稀疏矩阵(采用三元组表示)的基本运算实验报告
![实现稀疏矩阵(采用三元组表示)的基本运算实验报告](https://img.taocdn.com/s3/m/6f99e64c26fff705cd170a5d.png)
实现稀疏矩阵(采用三元组表示)的基本运算实验报告一实验题目: 实现稀疏矩阵(采用三元组表示)的基本运算二实验要求:(1)生成如下两个稀疏矩阵的三元组 a 和 b;(上机实验指导 P92 )(2)输出 a 转置矩阵的三元组;(3)输出a + b 的三元组;(4)输出 a * b 的三元组;三实验内容:稀疏矩阵的抽象数据类型:ADT SparseMatrix {数据对象:D={aij| i = 1,2,3,….,m; j =1,2,3,……,n;ai,j∈ElemSet,m和n分别称为矩阵的行数和列数}数据关系: R={ Row , Col }Row ={<ai,j ,ai,j+1> | 1≤i≤m , 1≤j ≤n-1}Col ={<a i,j , a i+1,j >| 1≤i≤m-1,1≤j ≤n}基本操作:CreateSMatrix(&M)操作结果:创建稀疏矩阵 M PrintSMatrix(M)初始条件:稀疏矩阵M已经存在操作结果:打印矩阵M DestroySMatrix(&M)初始条件:稀疏矩阵M已经存在操作结果:销毁矩阵M CopySMatrix(M, &T)初始条件:稀疏矩阵M已经存在操作结果:复制矩阵M到TAddSMatrix(M, N, &Q)初始条件:稀疏矩阵M、N已经存在操作结果:求矩阵的和Q=M+NSubSMatrix(M, N, &Q)初始条件:稀疏矩阵M、N已经存在操作结果:求矩阵的差Q=M-N TransposeSMatrix(M, & T)初始条件:稀疏矩阵M已经存在操作结果:求矩阵M的转置T MultSMatrix(M, N, &Q)初始条件:稀疏矩阵M已经存在操作结果:求矩阵的积Q=M*N}ADT SparseMatrix存储结构的定义#define N 4typedef int ElemType;#define MaxSize 100 =i;[].c=j;[].d=A[i][j];++;}}}void DispMat(TSMatrix t){int i;if <=0)return;printf("\t%d\t%d\t%d\n",,,;printf("\t------------------\n");for (i=0;i<;i++)printf("\t%d\t%d\t%d\n",[i].r,[i].c,[i].d); }解题思路:1.转置矩阵:只要判定原矩阵有值,那么只要遍历一遍原矩阵,把原来矩阵中非0元素行列变换一下赋值到新的矩阵中即可。
数据结构实验报告实验五稀疏矩阵运算器
![数据结构实验报告实验五稀疏矩阵运算器](https://img.taocdn.com/s3/m/db937d67bdd126fff705cc1755270722192e5930.png)
一、引言稀疏矩阵是一个具有大量零元素的矩阵,对于大规模的矩阵来说,如果没有充分利用矩阵的稀疏性质,将会带来很大的存储空间和计算时间上的浪费。
为了解决这个问题,我们需要通过设计一个稀疏矩阵运算器来对稀疏矩阵进行各种运算,以提高计算效率。
二、实验目标本实验的主要目标是设计一个稀疏矩阵运算器,通过实现对稀疏矩阵的加法、乘法和转置等操作,实现对稀疏矩阵的高效运算。
三、设计思路和方法1. 矩阵的表示方式在设计稀疏矩阵运算器时,我们需要选择合适的数据结构来表示稀疏矩阵。
由于稀疏矩阵中大部分元素为零,我们可以采用压缩存储的方法来表示稀疏矩阵。
一种常用的压缩存储方法是使用三元组表示法,即将矩阵的非零元素的值、所在的行号和列号分别存储在一个三元组中。
2. 加法运算稀疏矩阵的加法运算是指将两个稀疏矩阵进行对应位置的相加操作。
在进行稀疏矩阵的加法运算时,首先需要判断两个矩阵的维度是否相同,然后通过遍历两个矩阵的非零元素,将相同位置的元素进行相加得到结果。
3. 乘法运算稀疏矩阵的乘法运算是指将两个稀疏矩阵进行矩阵乘法操作。
在进行稀疏矩阵的乘法运算时,首先需要判断第一个矩阵的列数是否等于第二个矩阵的行数,然后通过遍历两个矩阵的非零元素,按照行和列的顺序对应相乘,再将相乘的结果加到结果矩阵中。
4. 转置运算稀疏矩阵的转置运算是指将矩阵的行和列对换。
在进行稀疏矩阵的转置运算时,只需要将矩阵的非零元素的行号和列号对换即可。
五、实验结果与分析我们在实现稀疏矩阵运算器后,对其进行了测试。
通过测试,我们发现稀疏矩阵运算器能够正确地进行稀疏矩阵的加法、乘法和。
稀疏矩阵课程设计实验报告
![稀疏矩阵课程设计实验报告](https://img.taocdn.com/s3/m/0990dc442e3f5727a5e962aa.png)
数据结构课程设计学院:信息科学与工程学院专业:计算机科学与技术班级:计算机1108学号:学生姓名:指导教师:2013 年 3 月 10 日稀疏矩阵一、实验内容基本要求:1.以“带行逻辑链接信息”的三元组顺序表表示稀疏矩阵,实现两个矩阵相加、想减、相乘的运算。
2.稀疏矩阵的输入形式采用三元组表表示,而运算结果则以通常的阵列形式输出选作内容:1.按书中的描述方法,以十字链表表示稀疏矩阵2.增添矩阵求逆的运算,包括不可求逆的情况。
在求逆之前,先将稀疏矩阵的内容表示改为十字链表…二、数据结构设计三元组结构体定义如下:#include <stdio.h>#include <stdlib.h>#define MAX 100typedef struct{int i,j;int e;}Triple;struct juzhen{Triple data[MAX+1];int first[MAX+1];int mv,nv,tv;};十字链表结构定义如下#include<stdio.h>#include<stdlib.h>#include<conio.h>typedef int ElemType;typedef struct CLNode{int row ;int col;ElemType fenzi;ElemType fenmu;CLNode * right;CLNode * down;}CLNode;typedef struct{CLNode ** rhead;CLNode ** chead;int ru;int lu;int tu;}CrossList;三、算法设计1.三元组表构建稀疏矩阵的定义如下:ADT Matrix{数据对象:D={a ij|i=1,2,…,m; j=1,2,…,n;a ij∈ElemSet, m和n分别为矩阵的行数和列数}数据关系:R={Row,Col }Row={﹤a i,j, a i,j+1﹥| 1≤i≤m, 1≤j≤n-1}Col = {﹤a i,j, a i+1,j﹥| 1≤i≤m-1, 1≤j≤n}基本操作:ChuangJian (XiShu &M)操作结果:创建稀疏矩阵矩阵TMShuChu(XiShu Q)操作结果:通常形式输出稀疏矩阵AddMatrix(XiShu M,XiShu N,XiShu *Q)操作结果:稀疏矩阵的加法运算:void JianMatrix(XiShu M,XiShu N,XiShu *Q)操作结果:稀疏矩阵的减法运算void ChengMatrix(XiShu M,XiShu N,XiShu *Q)操作结果:稀疏矩阵的乘法运算}ADT Matrix;2 十字链表创建稀疏矩阵的定义如下:ADT SparseMatrix{数据对象 D={a ij|i=1,2,3……m,j=1,2,3……n;a ij属于ElemSet,m和n分别是稀疏矩阵的行数和列数}数据关系 R={ Row, Col }Row={<a ij,a ij+1>|1<=i<=m,1<=j<=n-1}Col={<a ij,a i+1j>|1<=i<=m-1,1<=j<=n}基本操作:void Input( CrossList &D )操作结果:十字链表创建稀疏矩阵int Determinant( const CrossList &D ,int row , int line )操作结果:求稀疏矩阵行列式的值void Reduction( int &fenzi, int &fenmu )操作结果:分子分母约分CrossList *InverseMatrix( const CrossList &D )操作结果:求稀疏矩阵的逆矩阵void Output( const CrossList *E )操作结果:十字邻接矩阵的输出}ADT SparseMatrix3.1 功能模块图本功能分为四个模块3.2 算法思路3.2.1实现方法列出系统中的所有函数并说明函数的功能void main() //三元组表法和十字链表的主函数int ChuangJian(XiShu *M) //三元组表法创建稀疏矩阵void ShuChu(XiShu Q) //三元组表法输出稀疏矩阵void AddMatrix(XiShu M,XiShu N,XiShu *Q)//三元组表法实现相加功能void JianMatrix(XiShu M,XiShu N,XiShu *Q)//三元组表法实现相减功能void ChengMatrix(XiShu M,XiShu N,XiShu *Q)//三元组表法实现相乘功能int Determinant(CrossList &D ,int row ,int line )//行列式求值void Reduction( int &fenzi, int &fenmu ) //分子分母约分void Input( CrossList &D ) //十字链表输入函数CrossList *InverseMatrix(CrossList &D)//求稀疏矩阵的逆矩阵void Output( const CrossList *E ) //十字链表输出函数3.2.2 设计思想稀疏矩阵加法运算思路:首先判断两个矩阵行数列数是否相等,比较两个矩阵中不为0的元素的行数i 及列数j,将i与j都相等的前后两个元素值e相加,保持i,j不变储存在新的三元组中,不等的则分别储存在此新三元组中稀疏矩阵减法运算思路:将后一个矩阵的每一个非零元都乘以-1,再调用加法运算的函数稀疏矩阵乘法运算思路:逐个定位两个矩阵的非零元的位置,从第一个矩阵的第一行开始,再从第二个矩阵的第一列开始,找到非零元相乘相加,并利用累加器逐列累加稀疏矩阵求逆运算的思路:矩阵的逆等于矩阵的伴随矩阵除以矩阵行列式的值(1)定义全局变量#define MAX 100#define TRUE 1#define FAULT 0typedef int ElemType;(2)主函数模块说明主函数主要结构void main( ){ 初始化;Switch(){Case :接受命令;选择处理命令}不满足退出}void main( ){初始化;接受命令;选择处理命令}(3)其他模块说明(用文字描述,不要代码)int CreateSMatrix(TSMatrix *M){初始化;输入行数、列数、非零元个数for(){for()按行为主序输入每一个非零元赋值}返回结果}void PrintSMatrix(TSMatrix Q){两层for循环输出每一个非零元}void AddRLSMatrix(TSMatrix M,TSMatrix N,TSMatrix *Q){判断行数、列数是否对应相等,若均相等则相加并赋值否则依次判断行数、列数的大小并再次判断将值放在另一个数组里}Void JianRLSMatrix(TSMatrix M,TSMatrix N,TSMatrix *Q){两层for循环将第二个矩阵的每一个非零元变为他的负数再调用相加函数}void MultSMatrix(TSMatrix M,TSMatrix N,TSMatrix *Q){初始化判断第一个矩阵的行数时候等于第二个矩阵的列数然后逐个定位两个矩阵的非零元的位置,从第一个矩阵的第一行开始,再从第二个矩阵的第一列开始,找到非零元相乘相加,并利用累加器逐列累加}四、测试数据及程序运行情况三元组表实现加法运算三元组表实现乘法运算十字链表实现求逆运算五、实验过程中出现的问题及解决方案1)问题:运行过程中发现加法减法能正常运行,而乘法却在计算时出现问题。
实验七 稀疏矩阵
![实验七 稀疏矩阵](https://img.taocdn.com/s3/m/06fc2bb765ce050876321380.png)
实验报告七稀疏矩阵操作实验
班级:姓名:学号:专业:
一、实验目的:
1、了解多维数组的存储方式和存取特点
2、熟悉稀疏矩阵的存储方式
3、用三元组法实现稀疏矩阵的相、减、转置算法。
二、实验内容:(请采用模板类及模板函数实现)
1、稀疏矩阵三元组存储表示及基本操作算法实现
[实现提示] (同时可参见教材p130-p133页算法)函数、类名称等可自定义,部分变量请加上学号后3位。
也可自行对类中所定义的操作进行扩展。
所加载的库函数或常量定义及类的定义:
(1)稀疏矩阵的三元组顺序存储结构类定义:
自定义如下:
(2)构造稀疏矩阵算法;(输入参数自定义)
(3)打印稀疏矩阵算法;
(4)两稀疏矩阵相加,获得一新的矩阵的算法;(自行设计)
初始条件:稀疏矩阵M与N的行数和列数对应相等
(5)两稀疏矩阵相减,获得一新的矩阵的算法;(自行设计)
初始条件:稀疏矩阵M与N的行数和列数对应相等
(6)求稀疏矩阵M的转置矩阵T算法;
初始条件:M存在。
测试结果如下:
选做题:
1、实现多维数组的顺序存储表示和操作算法。
(操作函数自定义,可参见课件)
2、参考p134页,实现稀疏矩阵十字链表存储类定义和创建操作算法。
三、实验心得(含上机中所遇问题的解决办法,所使用到的编程技巧、创新点及编程的
心得)。
数据结构实验报告-特殊矩阵和稀疏矩阵
![数据结构实验报告-特殊矩阵和稀疏矩阵](https://img.taocdn.com/s3/m/daeeb07b1eb91a37f1115cc6.png)
实验五特殊矩阵和稀疏矩阵【实验目的】1、掌握数组的结构类型(静态的内存空间配置);通过数组的引用下标转换成该数据在内存中的地址;2、掌握对称矩阵的压缩存储表示;3、掌握稀疏矩阵的压缩存储-三元组表表示,以及稀疏矩阵的转置算法。
【实验学时】2学时【实验预习】回答以下问题:1、什么是对称矩阵?写出对称矩阵压缩存储sa[k]与aij之间的对应关系。
2、什么是稀疏矩阵?稀疏矩阵的三元组表表示。
【实验内容和要求】1、编写程序exp5_1.c,将对称矩阵进行压缩存储。
(1)对称矩阵数组元素A[i][j]转换成为以行为主的一维数组sa[k],请描述k与ij的关系。
(注意C程序中,i,j,k均从0开始)(2)调试程序与运行。
对称矩阵存储下三角部分即i>=j。
对称矩阵为3,9,1,4,79,5,2,5,81,2,5,2,44,5,2,1,77,8,4,7,9参考程序如下:#include<stdio.h>#define N 5int main(){int upper[N][N]= {{3,9,1,4,7},{9,5,2,5,8},{1,2,5,2,4},{4,5,2,1,7},{7,8,4,7,9}}; /*对称矩阵*/int rowMajor[15]; /*存储转换数据后以行为主的数组*/int Index; /*数组的索引值*/int i,j;printf("Two dimensional upper triangular array:\n");for (i=0; i<N; i++) /*输出对称矩阵*/{for(j=0; j<N; j++)printf("%3d",upper[i][j]);printf("\n");}for(i=0; i<N; i++) /*进行压缩存储*/for(j=0; j<N; j++)if(____i>=j_____) /*下三角元素进行存储*/{Index=______i*(i+1)/2+j______; /*ij与index的转换*/rowMajor[Index]=upper[i][j];}printf("\nRow Major one dimensional array:\n");for(i=0; i<15; i++) /*输出转换后的一维数组*/printf("%3d", rowMajor[i]);printf("\n");return 1;}2、完成程序exp5_2.c,实现稀疏矩阵的三元组表存储及稀疏矩阵的转置。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一.需求分析输入要求:稀疏矩阵的行、列和非零元素个数输出要求:稀疏矩阵的转置、加法、减法、乘法二.算法设计本程序中采用的数据模型,用到的抽象数据类型的定义,程序的主要算法流程及各模块之间的层次调用关系1.抽象数据类型:ADT List {数据对象:D={ai:|ai∈ElemSet,i=1…n,n≥0}数据关系:R={Row,Col}Row={<ai,j,ai,j>|1<=i<=m,1<=j<=n-1}Col={<ai,j,ai,j>|1<=i<=m-1,1<=j<=n}基本操作:Status CreateSMatrix(TSMatrix &M)操作结果:初始化稀疏数组void PrintSMatrix(TSMatrix M)初始条件:稀疏数组M已经存在操作结果:打印矩阵Mvoid DestroySMatrix(TSMatrix &M)初始条件:稀疏数组M已经存在操作结果:销毁矩阵Mvoid CopySMatrix(TSMatrix M, TSMatrix &T)初始条件:稀疏数组M已经存在操作结果:复制矩阵M到TStatus AddSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q)初始条件:稀疏数组M、N已经存在操作结果:求矩阵的和Q=M+NStatus SubSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q)初始条件:稀疏数组M、N已经存在操作结果:求矩阵的差Q=M-NStatus TransposeSMatrix(TSMatrix M, TSMatrix & T)初始条件:稀疏数组M已经存在操作结果:求矩阵M的转置TStatus MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q)初始条件:稀疏数组M已经存在操作结果:求矩阵的积Q=M*N}ADT List2. 本程序有二个模块:(1)主程序模块main(){初始化;{接受命令;显示结果;}}(2)三元组表单元模块:实现矩阵抽象数据类型。
三.程序设计根据算法设计中给出的有关数据和算法,选定物理结构,详细设计需求分析中所要求的程序。
包括:人机界面设计、主要功能的函数设计、函数之间调用关系描述等。
1、程序基本结构:2、稀疏矩阵的三元组顺序表存储表示:typedef struct { // 定义三元组的元素int i, j;int e;} Triple;typedef struct { // 定义普通三元组对象Triple data[MAXSIZE + 1];int mu, nu, tu;} TSMatrix;typedef struct { // 定义带链接信息的三元组对象Triple data[MAXSIZE + 2];int rpos[MAXROW + 1];int mu, nu, tu;} RLSMatrix;3、基本函数:1)输入矩阵,按三元组格式输入bool InPutTSMatrix(P & T, int y) {cout << "输入矩阵的行,列和非零元素个数:" << endl;cin >> T.mu >> T.nu >> T.tu;cout << "请输出非零元素的位置和值:" << endl;int k = 1;for (; k <= T.tu; k++)cin >> T.data[k].i >> T.data[k].j >> T.data[k].e;return true;}2)输出矩阵,按标准格式输出bool OutPutSMatrix(P T) {int m, n, k = 1;for (m = 0; m < T.mu; m++) {for (n = 0; n < T.nu; n++) {if ((T.data[k].i - 1) == m && (T.data[k].j - 1) == n) {cout.width(4);cout << T.data[k++].e;} else {cout.width(4);cout << "0";}}cout << endl;}return true;}3)求矩阵的转置矩阵bool TransposeSMatrix() {TSMatrix M, T; //定义预转置的矩阵InPutTSMatrix(M, 0); //输入矩阵int num[MAXROW + 1];int cpot[MAXROW + 1]; //构建辅助数组int q, p, t;T.tu = M.tu;T.mu = M.nu;T.nu = M.mu;if (T.tu) {for (int 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 (int i = 2; i <= M.nu; i++) cpot[i] = cpot[i - 1] + num[i - 1];for (p = 1; p <= M.tu; p++) {int col = M.data[p].j;q = cpot[col];T.data[q].i = col;T.data[q].j = M.data[p].i;T.data[q].e = M.data[p].e;++cpot[col];}}cout << "输入矩阵的转置矩阵为" << endl;OutPutSMatrix(T);return true;}4)两个矩阵相乘bool MultSMatrix() {RLSMatrix M, N, Q; // 构建三个带“链接信息”的三元组表示的数组InPutTSMatrix(M, 1); //用普通三元组形式输入数组InPutTSMatrix(N, 1);Count(M);Count(N);if (M.nu != N.mu) return false;Q.mu = M.mu;Q.nu = N.nu;Q.tu = 0; //Q初始化int ctemp[MAXROW + 1]; //辅助数组int arow, tp, p, brow, t, q, ccol;if (M.tu * N.tu) { // Q是非零矩阵for (arow = 1; aro w <= M.mu; aro w++) {///memset(ctemp,0,N.nu);for (int x = 1; x <= N.nu; x++)ctemp[x] = 0;Q.rpos[arow] = Q.tu + 1; // 当前行的首个非零元素在三元组中的位置为此行前所有非零元素+1if (arow < M.mu) tp = M.rpos[arow + 1];else tp = M.tu + 1;for (p = M.rpos[aro w]; p < tp; p++) { // 对当前行每个非零元素进行操作brow = M.data[p].j; // 在N中找到i值也操作元素的j值相等的行if (brow < N.mu) t = N.rpos[brow + 1];else t = N.tu + 1;for (q = N.rpos[brow]; q < t; q++) { // 对找出的行当每个非零元素进行操作ccol = N.data[q].j;ctemp[ccol] += M.data[p].e * N.data[q].e; //将乘得到对应值放在相应的元素累加器里面}}for (ccol = 1; ccol <= Q.nu; ccol++) // 对已经求出的累加器中的值压缩到Q中if (cte mp[ccol]) {if (++Q.tu > MAXSIZE) return false;Q.data[Q.tu].e = ctemp[ccol];Q.data[Q.tu].i = arow;Q.data[Q.tu].j = ccol;}}}OutPutSMatrix(Q);return true;}5)矩阵的加法bool AddSMatrix() {CrossList M, N; // 创建两个十字链表对象,并初始化CreateSMatrix_OL(M);CreateSMatrix_OL(N);cout << "输入的两矩阵的和矩阵为:" << endl;OLink pa, pb, pre, hl[MAXROW + 1]; //定义辅助指针,pa,pb分别为M,N当前比较的元素,pre为pa的前驱元素for (int x = 1; x <= M.nu; x++) hl[x] = M.chead[x];for (int k = 1; k <= M.mu; k++) { // 对M的每一行进行操作pa = M.rhead[k];pb = N.rhead[k];pre = NULL;while (pb) { // 把N中此行的每个元素取出,OLink p;if (!(p = (OLink) malloc(sizeof (OLNode)))) exit(0); // 开辟新节点,存储N中取出的元素p->e = pb->e;p->i = pb->i;p->j = pb->j;if (NULL == pa || pa->j > pb->j) { // 当M此行已经检查完或者pb因该放在pa前面if (NULL == pre)M.rhead[p->i] = p;elsepre->right = p;p->right = pa;pre = p;if (NULL == M.chead[p->j]) { // 进行列插入M.chead[p->j] = p;p->do wn = NULL;} else {p->do wn = hl[p->j]->down;hl[p->j]->do wn = p;}hl[p->j] = p;pb = pb->right;} elseif ((NULL != pa) && pa->j < pb->j) { // 如果此时的pb元素因该放在pa后面,则取以后的pa再来比较pre = pa;pa = pa->right;} elseif (pa->j == pb->j) { // 如果pa,pb位于同一个位置上,则将值相加pa->e += pb->e;if (!pa->e) { // 如果相加后的和为0,则删除此节点,同时改变此元素坐在行,列的前驱元素的相应值if (NULL == pre) // 修改行前驱元素值M.rhead[pa->i] = pa->right;elsepre->right = pa->right;p = pa;pa = pa->right;if (M.chead[p->j] == p) M.chead[p->j] = hl[p->j] = p->down; // 修改列前驱元素值elsehl[p->j]->do wn = p->do wn;free(p);pb = pb->right;} else {pa = pa->right;pb = pb->right;}}}}OutPutSMatrix_OL(M);return true;}4、各模块间的关系:四.测试与分析1、测试结果输入1选择矩阵倒置:输入2选择矩阵的加法: main InPutTSMat rix TransposeSMa AddSMatrix MultSMatrixOutPutSMatrix输入3选择矩阵的乘法:2、分析与遇到的问题1)创建稀疏矩阵时,不懂如何用三元组表示元素的输出;2)需要注意矩阵运算中的特殊状况,比如:稀疏矩阵相加时,忘记对应元素相加为0时,在稀疏矩阵中不表示;矩阵相乘时,必须符合第一个矩阵的列数等于第二个矩阵的行数;矩阵相加时,第一个矩阵的行列数要和第二个矩阵的行列数相等;附录:源代码#include <iostream>#include <iomanip>using namespace std;const int MAXSIZE = 100; // 定义非零元素的对多个数const int MAXROW = 10; // 定义数组的行数的最大值typedef struct {int i, j;int e;} Triple; // 定义三元组的元素typedef struct {Triple data[MAXSIZE + 1];int mu, nu, tu;} TSMatrix; // 定义普通三元组对象typedef struct {Triple data[MAXSIZE + 2];int rpos[MAXROW + 1];int mu, nu, tu;} RLSMatrix; // 定义带链接信息的三元组对象typedef struct OLNode { // 定义十字链表元素int i, j;int e;struct OLNode *right, *down; // 该非零元所在行表和列表的后继元素} OLNode, *OLink; // 定义十字链表元素typedef struct { // 定义十字链表对象结构体OLink *rhead, *chead;int mu, nu, tu; // 系数矩阵的行数,列数,和非零元素个数} CrossList; // 定义十字链表对象结构体template <class P>bool InPutTSMatrix(P & T, int y) { //输入矩阵,按三元组格式输入cout << "输入矩阵的行,列和非零元素个数:" << endl;cin >> T.mu >> T.nu >> T.tu;cout << "请输出非零元素的位置和值:" << endl;int k = 1;for (; k <= T.tu; k++)cin >> T.data[k].i >> T.data[k].j >> T.data[k].e;return true;}template <class P>bool OutPutSMatrix(P T) {int m, n, k = 1;for (m = 0; m < T.mu; m++) {for (n = 0; n < T.nu; n++) {if ((T.data[k].i - 1) == m && (T.data[k].j - 1) == n) {cout.width(4);cout << T.data[k++].e;} else {cout.width(4);cout << "0";}}cout << endl;}return true;}// 输出矩阵,按标准格式输出bool TransposeSMatrix() {TSMatrix M, T; //定义预转置的矩阵InPutTSMatrix(M, 0); //输入矩阵int num[MAXROW + 1];int cpot[MAXROW + 1]; // 构建辅助数组int q, p, t;T.tu = M.tu;T.mu = M.nu;T.nu = M.mu;if (T.tu) {for (int 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 (int i = 2; i <= M.nu; i++) cpot[i] = cpot[i - 1] + num[i - 1]; // 求出每一列中非零元素在三元组中出现的位置for (p = 1; p <= M.tu; p++) {int col = M.data[p].j;q = cpot[col];T.data[q].i = col;T.data[q].j = M.data[p].i;T.data[q].e = M.data[p].e;++cpot[col];}}cout << "输入矩阵的转置矩阵为" << endl;OutPutSMatrix(T);return true;}// 求矩阵的转置矩阵bool Count(RLSMatrix &T) {int num[MAXROW + 1];for (int col = 1; col <= T.mu; col++) num[col] = 0;for (int col = 1; col <= T.tu; col++) ++num[T.data[col].i];T.rpos[1] = 1;for (int i = 2; i <= T.mu; i++) T.rpos[i] = T.rpos[i - 1] + num[i - 1]; // 求取每一行中非零元素在三元组中出现的位置return true;}bool MultSMatrix() {RLSMatrix M, N, Q; // 构建三个带“链接信息”的三元组表示的数组InPutTSMatrix(M, 1); // 用普通三元组形式输入数组InPutTSMatrix(N, 1);Count(M);Count(N);cout << "输入的两矩阵的乘矩阵为:" << endl;if (M.nu != N.mu) return false;Q.mu = M.mu;Q.nu = N.nu;Q.tu = 0; // Q初始化int ctemp[MAXROW + 1]; // 辅助数组int arow, tp, p, brow, t, q, ccol;if (M.tu * N.tu) { // Q是非零矩阵for (arow = 1; arow <= M.mu; arow++) {///memset(ctemp,0,N.nu);for (int x = 1; x <= N.nu; x++) // 当前行各元素累加器清零ctemp[x] = 0;Q.rpos[arow] = Q.tu + 1; // 当前行的首个非零元素在三元组中的位置为此行前所有非零元素+1if (arow < M.mu) tp = M.rpos[arow + 1];else tp = M.tu + 1;for (p = M.rpos[arow]; p < tp; p++) { // 对当前行每个非零元素进行操作brow = M.data[p].j; // 在N中找到i值也操作元素的j 值相等的行if (brow < N.mu) t = N.rpos[brow + 1];else t = N.tu + 1;for (q = N.rpos[brow]; q < t; q++) { // 对找出的行当每个非零元素进行操作ccol = N.data[q].j;ctemp[ccol] += M.data[p].e * N.data[q].e; // 将乘得到对应值放在相应的元素累加器里面}}for (ccol = 1; ccol <= Q.nu; ccol++) // 对已经求出的累加器中的值压缩到Q中if (ctemp[ccol]) {if (++Q.tu > MAXSIZE) return false;Q.data[Q.tu].e = ctemp[ccol];Q.data[Q.tu].i = arow;Q.data[Q.tu].j = ccol;}}}OutPutSMatrix(Q);return true;}// 两个矩阵相乘bool CreateSMatrix_OL(CrossList & M) {int x, y, m;cout << "请输入矩阵的行,列,及非零元素个数" << endl;cin >> M.mu >> M.nu >> M.tu;if (!(M.rhead = (OLink*) malloc((M.mu + 1) * sizeof (OLink)))) exit(0);if (!(M.chead = (OLink*) malloc((M.nu + 1) * sizeof (OLink)))) exit(0);for (x = 0; x <= M.mu; x++)M.rhead[x] = NULL; // 初始化各行,列头指针,分别为NULL for (x = 0; x <= M.nu; x++)M.chead[x] = NULL;cout << "请按三元组的格式输入数组:" << endl;for (int i = 1; i <= M.tu; i++) {cin >> x >> y >> m; // 按任意顺序输入非零元,(普通三元组形式输入)OLink p, q;if (!(p = (OLink) malloc(sizeof (OLNode)))) exit(0); // 开辟新节点,用来存储输入的新元素p->i = x;p->j = y;p->e = m;if (M.rhead[x] == NULL || M.rhead[x]->j > y) {p->right = M.rhead[x];M.rhead[x] = p;} else {for (q = M.rhead[x]; (q->right) && (q->right->j < y); q = q->right); // 查找节点在行表中的插入位置p->right = q->right;q->right = p; // 完成行插入}if (M.chead[y] == NULL || M.chead[y]->i > x) {p->down = M.chead[y];M.chead[y] = p;} else {for (q = M.chead[y]; (q->down) && (q->down->i < x); q = q->down); // 查找节点在列表中的插入位置p->down = q->down;q->down = p; // 完成列插入}}return true;}// 创建十字链表bool OutPutSMatrix_OL(CrossList T) { // 输出十字链表,用普通数组形式输出for (int i = 1; i <= T.mu; i++) {OLink p = T.rhead[i];for (int j = 1; j <= T.nu; j++) {if ((p) && (j == p->j)) {cout << setw(3) << p->e;p = p->right;} elsecout << setw(3) << "0";}cout << endl;}return true;}//输出十字链表bool AddSMatrix() {CrossList M, N; // 创建两个十字链表对象,并初始化CreateSMatrix_OL(M);CreateSMatrix_OL(N);cout << "输入的两矩阵的和矩阵为:" << endl;OLink pa, pb, pre, hl[MAXROW + 1]; //定义辅助指针,pa,pb分别为M,N当前比较的元素,pre为pa的前驱元素for (int x = 1; x <= M.nu; x++) hl[x] = M.chead[x];for (int k = 1; k <= M.mu; k++) { // 对M的每一行进行操作pa = M.rhead[k];pb = N.rhead[k];pre = NULL;while (pb) { // 把N中此行的每个元素取出,OLink p;if (!(p = (OLink) malloc(sizeof (OLNode)))) exit(0); // 开辟新节点,存储N中取出的元素p->e = pb->e;p->i = pb->i;p->j = pb->j;if (NULL == pa || pa->j > pb->j) { // 当M此行已经检查完或者pb因该放在pa前面if (NULL == pre)M.rhead[p->i] = p;elsepre->right = p;p->right = pa;pre = p;if (NULL == M.chead[p->j]) { // 进行列插入M.chead[p->j] = p;p->down = NULL;} else {p->down = hl[p->j]->down;hl[p->j]->down = p;}hl[p->j] = p;pb = pb->right;} elseif ((NULL != pa) && pa->j < pb->j) { // 如果此时的pb 元素因该放在pa后面,则取以后的pa再来比较pre = pa;pa = pa->right;} elseif (pa->j == pb->j) { // 如果pa,pb位于同一个位置上,则将值相加pa->e += pb->e;if (!pa->e) { // 如果相加后的和为0,则删除此节点,同时改变此元素坐在行,列的前驱元素的相应值if (NULL == pre) // 修改行前驱元素值M.rhead[pa->i] = pa->right;elsepre->right = pa->right;p = pa;pa = pa->right;if (M.chead[p->j] == p) M.chead[p->j] = hl[p->j] = p->down; // 修改列前驱元素值elsehl[p->j]->down = p->down;free(p);pb = pb->right;} else {pa = pa->right;pb = pb->right;}}}}OutPutSMatrix_OL(M);return true;}//矩阵的加法int main() {cout.fill('*');cout << setw(80) << '*';cout.fill(' ');// system("color 0C");cout << setw(50) << "***欢迎使用矩阵运算程序***" << endl; //输出头菜单cout.fill('*');cout << setw(80) << '*';cout.fill(' ');cout << " 请选择要进行的操作:" << endl;cout << " 1:矩阵的转置。