数据结构课程设计稀疏矩阵
【数据结构算法】实验3 稀疏矩阵基本操作-顺序结构(附源代码)

浙江大学城市学院实验报告课程名称数据结构与算法实验项目名称实验三稀疏矩阵的基本操作--用顺序存储结构实验成绩指导老师(签名)日期一.实验目的和要求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的当前元素行号相等时相乘两个数,并将结果暂存入单链表。
数据结构+课程设计+稀疏矩阵的操作(计算机学院)

计算机科学技术学院学生课程设计(论文)题目:学生姓名:学号:所在院(系):专业:班级:指导教师:职称:年月日计算机科学技术学院本科学生课程设计任务书注:任务书由指导教师填写。
课程设计(论文)指导教师成绩评定表稀疏矩阵的操作1.课程设计的目的本课程设计是为了配合《数据结构》课程的开设,通过设计一完整的程序,使学生掌握数据结构的应用、算法的编写、类C语言的算法转换成C程序并用TC上机调试的基本方法。
利用三元组实现稀疏矩阵的有关算法。
2.问题描述2.1稀疏矩阵采用三元组表示,求两个具有相同行列数的稀疏矩阵A和B的相加矩阵C,并输出C。
2.2求出A的转置矩阵D,输出D。
3. 基本要求稀疏矩阵是指那些多数元素为零的矩阵。
利用“稀疏”特点进行存储和计算可以大大节省存储空间,提高计算效率。
实现一个能进行稀疏矩阵基本运算的运算器。
以“带行逻辑链接信息”的三元组顺序表表示稀疏矩阵,实现两个矩阵相加、相减和相乘的运算。
稀疏矩阵的输入形式采用三元组表示,而运算结果的矩阵则通常以阵列形式列出。
4.结构设计4.1.以“带行逻辑链接信息”的三元组顺序表表示稀疏矩阵,实现两个矩阵相加、相减和相乘的运算。
4.2.稀疏矩阵的输入形式采用三元组表示,而运算结果的矩阵则通常以阵列形式列出。
4.3.首先应输入矩阵的行数和列数,并判别给出的两个矩阵的行、列数对于所要求作的运算是否相匹配。
可设矩阵的行数和列数均不超过20。
4.4.程序可以对三元组的输入顺序加以限制,例如,按行优先。
注意研究教材的算法,以便提高计算效率。
5.在用三元组表示稀疏矩阵时,相加或相减所得结果矩阵应该另生成,乘积矩阵也可用二维数组存放5.算法思想5.1.主函数设置循环和选择语句进行运算循环和选择,进行稀疏矩阵的加法,减法,乘法,转置和是否继续运算5个分支开关进行运算选择。
5.2.设置函数分别实现稀疏矩阵的输入,输出,加法,减法,乘法。
5.3.在数组结构体中设置存放每行第一个非零元在其数组存储结构单元的位置的存储单元,若该行无非零元,则存为06.模块划分6.1typedef struct存放各行第一个非零元在存储数组中的位置,若该行无非零元,则其rpos[]值为零6.2 createsmatrix(rlsmatrix *M) 矩阵输入函数,输入各行非零元及其在矩阵中的行列数6.3 FasttransposeRLSMatrix(RLSMatrix M,RLSMatrix *Q) 矩阵快速转置6.4 HeRLSMatrix(RLSMatrix *M,RLSMatrix *N,RLSMatrix *Q) 矩阵求和6.5 ChaRLSMatrix(RLSMatrix *M,RLSMatrix *N,RLSMatrix *Q) 矩阵求差6.6 JiRLSMatrix(RLSMatrix M,RLSMatrix N,RLSMatrix *Q) 矩阵求积7.算法实现7.1首先定义非零元个数的最大值和存放各行第一个非零元在存储数组中的位置#include<stdio.h>#define MAXSIZE 100 /* 非零元个数的最大值*/typedef struct triple{int i,j; /* 行下标,列下标*/int e; /* 非零元素值*/}triple;typedef struct tsmatrix{triple data[MAXSIZE+1]; /* 非零元三元组表,data[0]未用*/int mu,nu,tu; /* 矩阵的行数、列数和非零元个数*//* 各列第一个非零元的位置表rpos[0]未用*/}rlsmatrix;7.2创建稀疏矩阵矩阵的行数,列数,和非零元素的个数并按行序顺序输入第%d 个非零元素所在的行(1~%d),列(1~%d),元素值。
数据结构实验2稀疏矩阵的建立与转置

实验2 稀疏矩阵的建立与转置(一)实验目的掌握特殊矩阵的存储和操作算法。
(二)问题描述实现用三元组保存稀疏矩阵并实现矩阵转置的算法。
(三)实验步骤1. 定义稀疏矩阵的三元组形式的存储结构。
2. 实现三元组矩阵的传统转置算法(pp99 的算法5.1)。
3. 实现三元组矩阵的快速转置算法。
4. 输入矩阵非零元素,测试自己完成的算法。
(四)程序流程图(五)参考代码#include <malloc.h>#include <stdio.h>#define MAXLEN 40typedef struct{ int i, j;int v;}NODE;typedef struct{ int m, n, t;NODE data[MAXLEN];}SPMA TRIX;SPMA TRIX transpose(SPMA TRIX a){/*稀疏矩阵(三元组存储结构)转置算法*/int p, q, col;SPMA TRIX b;b.m=a.n; b.n=a.m; b.t=a.t;if(a.t!=0){q = 1;for (col=1; col<=a.n; col++) //访问b三元组的每一行for (p=1; p<=a.t; p++) //访问a三元组的每一行if(a.data[p].j==col) //如果b三元组的行对应a数组的列,就进行转置{ b.data[q].j=a.data[p].i;b.data[q].i=a.data[p].j;b.data[q].v=a.data[p].v;q++;}}return b;}void printmatrix(SPMA TRIX c){/*稀疏矩阵(三元组存储结构)显示*/int n,i;n=c.t;for(i=1;i<=n;i++)printf("[%d]行号=%d 列号=%d 元素值=%d\n",i,c.data[i].i,c.data[i].j,c.data[i].v);}void main(){ SPMA TRIX a;SPMA TRIX b;int i,j,r,c,t,n;n=1;printf("\n\n输入矩阵行号数: ");scanf("%d",&r);printf("\n\n输入矩阵列号数: ");scanf("%d",&c);a.m=r; a.n=c;printf("\n\n");for(i=0;i<r;i++) /*输入矩阵元素值*/for(j=0;j<c;j++){printf("输入元素[%d,%d]值: ",i+1,j+1);scanf("%d",&t);if(t!=0) {a.data[n].i=i+1; /*非零元素存入稀疏矩阵三元组存储结构中*/a.data[n].j=j+1; a.data[n].v=t; n=n+1;}}n=n-1; a.t=n; /*a.t中为稀疏矩阵非零元素个数*/printf("\n\n稀疏矩阵三元组表示: \n\n");printmatrix(a); /*稀疏矩阵(三元组存储结构)转置*/b=transpose(a);printf("\n\n转置后稀疏矩阵三元组表示: \n\n");printmatrix(b);printf("\n\n");}(六)运行结果(七)心得体会掌握了特殊矩阵的存储和操作原理,编写了用三元组保存稀疏矩阵并实现矩阵转置的算法。
三元组顺序表稀疏矩阵课程设计报告(不完整)

1.稀疏矩阵运算器数据结构课程设计任务书针对本课程设计,完成以下课程设计任务:1、熟悉系统实现工具和上机环境。
2、根据课程设计任务,查阅相关资料。
3、针对所选课题完成以下工作:(1)需求分析(2)概要分析(3)详细设计(4)编写源程序(5)静态走查程序和上机调试程序4、书写上述文档和撰写课程设计报告。
3.课程设计报告目录4.正文(1)问题描述稀疏矩阵是指那些多数元素为零的矩阵。
利用“稀疏”特点进行存储和计算可以大大节省存储空间,提高计算频率。
实现一个能进行稀疏矩阵基本运算的运算器。
(2)需求分析本课程设计的稀疏矩阵运算器在visual studio 2013下运行调试成功,可以实现的功能有:1.矩阵运算方式选择2.根据提示输入相应数据3.显示最终结果使用的主要存储结构为三元组,并用三元组形式进行运算。
所有参与运算数据类型为整形,因此输入的数据应为整形数据。
为了节省存储空间使用三元组数据进行运算,可以通过多次扫描三元组数据来实现,即使用嵌套循环函数。
输出结果为通常的阵列形式,因此使用了右对齐,保证输出形式的整齐。
(3)概要分析本次课程设计中定义的结构体typedef struct {int i, j;//矩阵元素所在行列int v;//元素的值}triple;typedef struct {triple data[MAXSIZE];triple cop[MAXSIZE];//辅助数组int m, n, t;//矩阵的行列数}tripletable;Main函数调用子函数时输入1为调用int Push_juzhen(int m, int n, int count)函数,可以实现矩阵相加功能输入2为调用int Dec_juzhen(int m, int n, int count)函数,可实现矩阵相减功能输入3为调用int Mul_juzhen()函数,可以实现矩阵相乘功能(4)详细分析(流程图伪代码)加法函数int Push_juzhen(int m, int n, int count)//矩阵相加(行,列,矩阵数){// p行,q列,s非零元素个数,v元素值//ucount对数组下标计数的变量,与变量x实现多个矩阵相加for (int c = 0; c < count; c++){int x = 0;cout << "请输入第" << c + 1 << "个矩阵的非零元素个数" << endl;cin >> s;cout << "请依次输入非零元素所在行和列以及该非零元素的值并以空格隔开" << endl;for (; x< s; x++)//传递行列及元素值{cin >> p >> q >> v;a.cop[x].i = p;//将p赋值给data[x].ia.cop[x].j = q;//将q赋值给data[x].ja.cop[x].v = v;//将v赋值给data[x].v}//g行//h列for (int g = 1; g <= m;g++)for (int h = 1; h <= n; h++){int l;//存储下标for (l = 0; l < s; l++)//对辅助存储中的三元组进行行逻辑排序,将数据存入a.data{if (a.cop[l].i == g&&a.cop[l].j == h){a.data[u].i = a.cop[l].i;a.data[u].j = a.cop[l].j;a.data[u].v = a.cop[l].v;u++;}}}}//矩阵相加//k为行数//h为列数for (int k = 0; k < u; k++){for (int h = 0; h <= ucount; h++){if (a.data[k].i == b.data[h].i&&a.data[k].j == b.data[h].j)//判断行列是否相等b.data[h].v += a.data[k].v;else{b.data[ucount].i = a.data[k].i;b.data[ucount].j = a.data[k].j;b.data[ucount].v = a.data[k].v;ucount++;//存储空间增加计数}break;//增加一组数据时跳出循环,避免重复计算}}return 0;}相减函数int Dec_juzhen(int m, int n, int count){for (int c = 0; c < count; c++){int x = 0;cout << "请输入第" << c + 1 << "个矩阵的非零元素个数" << endl;cin >> s;cout << "请依次输入非零元素所在行和列以及该非零元素的值并以空格隔开" << endl;for (; x< s; x++)//传递行列及元素值{cin >> p >> q >> v;a.cop[x].i = p;//将p赋值给data[x].ia.cop[x].j = q;//将q赋值给data[x].ja.cop[x].v = v;//将v赋值给data[x].v}//g行//h列if (c != 0){for (int g = 1; g <= m; g++)for (int h = 1; h <= n; h++){int l;//存储下标for (l = 0; l < s; l++)//行逻辑排列{if (a.cop[l].i == g&&a.cop[l].j == h){ a.data[u].i = a.cop[l].i;a.data[u].j = a.cop[l].j;a.data[u].v =- a.cop[l].v;//c>0时为减数矩阵u++;}}}}else{for (int g = 1; g <= m; g++)for (int h = 1; h <= n; h++){int l;//存储下标for (l = 0; l < s; l++){if (a.cop[l].i == g&&a.cop[l].j == h){a.data[u].i = a.cop[l].i;a.data[u].j = a.cop[l].j;a.data[u].v = a.cop[l].v;u++;}}}}}//矩阵减法计算for (int k = 0; k < u; k++){for (int h = 0; h <= ucount; h++){if (a.data[k].i == b.data[h].i&&a.data[k].j == b.data[h].j)//判断行列相等b.data[h].v += a.data[k].v;else{b.data[ucount].i = a.data[k].i;b.data[ucount].j = a.data[k].j;b.data[ucount].v = a.data[k].v;ucount++;}break;}}return 0;}相乘函数int Mul_juzhen(){cout << "请输入第一个矩阵的行列数" << endl;cin >> m >> n;cout << "请输入第一个矩阵的非零元素个数" << endl;cin >> t1;a.m = m;a.n = n;a.t = t1;cout << "请输入第一个矩阵的非零元素所在的行、列、数值并以空格间隔" << endl;for (i=0; i < t1; i++){cin >> p >> q >> v;a.data[i].i = p;//将p赋值给data[x].ia.data[i].j = q;//将q赋值给data[x].ja.data[i].v = v;//将v赋值给data[x].v}cout << "则第二个矩阵的行数为" << a.n << "行" << endl<<endl;cout << "请输入第二个矩阵的列数" << endl;cin >> n;cout << "请输入第二个矩阵的非零元素个数" << endl;cin >> t2;b.m = a.n;b.n = n;b.t = t2;cout << "请输入第二个矩阵的非零元素所在的行、列、数值并以空格间隔" << endl;for (i = 0; i < t2; i++){cin >> p >> q >> v;b.data[i].i = p;//将p赋值给data[x].ib.data[i].j = q;//将q赋值给data[x].jb.data[i].v = v;//将v赋值给data[x].v}i = 0;//i为a、b数组标记,另设k为矩阵相乘元素扫描标记//n为检测相加元素扫描标记,z为存储标记while (i < a.t){int k;for (k = 0; k < b.t; k++){if (a.data[i].j == b.data[k].i)if (i>0){for (n = 0; n < z; n++){if (a.data[i].i == c.data[n].i&&b.data[k].j == c.data[n].j)//判断是否符合相加条件c.data[n].v += a.data[i].v*b.data[k].v;else{c.data[z].i = a.data[i].i;c.data[z].j = b.data[k].j;c.data[z].v = a.data[i].v*b.data[k].v;z++;}}}else{c.data[z].i = a.data[i].i;c.data[z].j= b.data[k].j;c.data[z].v = a.data[i].v*b.data[k].v;z++;}}i++;}return 0;}(5)调试分析(遇到的问题,修改,解决办法,时空复杂度)刚开始,程序仅使用三元组存储,计算过程使用了二维数组,但矩阵相乘会出现错误,矩阵乘法时间复杂度为矩阵一的行数乘以矩阵二的列数(m1*n2)。
数据结构实验报告稀疏矩阵运算

数据结构实验报告稀疏矩阵运算实验目的:1.学习并理解稀疏矩阵的概念、特点以及存储方式。
2.掌握稀疏矩阵加法、乘法运算的基本思想和算法。
3.实现稀疏矩阵加法、乘法的算法,并进行性能测试和分析。
实验原理:稀疏矩阵是指矩阵中绝大多数元素为0的矩阵。
在实际问题中,有许多矩阵具有稀疏性,例如文本矩阵、图像矩阵等。
由于存储稀疏矩阵时,对于大量的零元素进行存储是一种浪费空间的行为,因此需要采用一种特殊的存储方式。
常见的稀疏矩阵的存储方式有三元组顺序表、十字链表、行逻辑链接表等。
其中,三元组顺序表是最简单直观的一种方式,它是将非零元素按行优先的顺序存储起来,每个元素由三个参数组成:行号、列号和元素值。
此外,还需要记录稀疏矩阵的行数、列数和非零元素个数。
稀疏矩阵加法的原理是将两个稀疏矩阵按照相同的行、列顺序进行遍历,对于相同位置的元素进行相加,得到结果矩阵。
稀疏矩阵乘法的原理是将两个稀疏矩阵按照乘法的定义进行计算,即行乘以列的和。
实验步骤:1.实现稀疏矩阵的三元组顺序表存储方式,并完成稀疏矩阵的初始化、转置、打印等基本操作。
2.实现稀疏矩阵的加法运算,并进行性能测试和分析。
3.实现稀疏矩阵的乘法运算,并进行性能测试和分析。
4.编写实验报告。
实验结果:经过实验测试,稀疏矩阵的加法和乘法算法都能正确运行,并且在处理稀疏矩阵时能够有效节省存储空间。
性能测试结果表明,稀疏矩阵加法、乘法的运行时间与非零元素个数有关,当非零元素个数较少时,运算速度较快;当非零元素个数较多时,运算速度较慢。
实验分析:稀疏矩阵的运算相对于普通矩阵的运算有明显的优势,可以节省存储空间和运算时间。
在实际应用中,稀疏矩阵的存储方式和运算算法都可以进行优化。
例如,可以采用行逻辑链接表的方式存储稀疏矩阵,进一步减少存储空间的占用;可以采用并行计算的策略加快稀疏矩阵的运算速度。
总结:通过本次实验,我深入学习了稀疏矩阵的概念、特点和存储方式,掌握了稀疏矩阵加法、乘法的基本思想和算法,并通过实验实现了稀疏矩阵的加法、乘法运算。
数据结构 稀疏矩阵运算器课程设计

数据结构----稀疏矩阵运算器课程设计目录稀疏矩阵运算器设计............................................................................................ I摘要................................................................................................................ ... II第一章需求分析 (1)第二章概要设计 (2)第三章设计步骤 (6)3.1 函数说明 (6)3.2 设计步骤 (7)第四章设计理论分析方法 (20)4.1 算法一:矩阵转置.....................................................................204.2 算法二:矩阵加法.....................................................................204.3 算法三:矩阵乘法 (21)第五章程序调试 (23)第六章心得体会 (25)参考文献 (26)第一章需求分析1.稀疏矩阵是指那些多数元素为零的矩阵。
利用“稀疏”特点进行存储和计算可以大大节省存储空间,提高计算效率。
实现一个能进行稀疏矩阵基本运算的运算器。
2.以“带行逻辑链接信息”的三元组顺序表表示稀疏矩阵,实现矩阵转置,求逆,实现两个矩阵相加、相减和相乘的运算。
稀疏矩阵的输入形式采用三元组表示,而运算结果的矩阵则以通常的阵列形式列出。
3.演示程序以用户和计算机的对话方式执行,数组的建立方式为边输入边建立。
4.由题目要求可知:首先应输入矩阵的行数和列数,并判别给出的两个矩阵的行、列数对于所要求作的运算是否相匹配。
5.程序可以对三元组的输入顺序不加以限制;根据对矩阵的行列,三元组作直接插入排序,从而进行运算时,不会产生错误。
数据结构课程设计之稀疏矩阵运算器

数据结构课程设计之稀疏矩阵运算器#include#include#define maxsize 200typedef struct{int i,j;//i为非零元素在行,j为非零元所在列int e;//非零元}Tripe;typedef struct{Tripe data[maxsize];int h,l,total;//稀疏矩阵的行数列数及非零元个数}TSMatrix;void Creat(TSMatrix &M){//创建一个稀疏矩阵int a,b,c,x;scanf("%d,%d,%d",&M.h,&M.l,&M.total);for(x=1;x<=M.total;x++){printf("请输入第%d个稀疏矩阵的非零元素所在的行数列数用逗号隔开输完按回车键:\",x);scanf("%d,%d,%d",&a,&b,&c);M.data[x].i=a;M.data[x].j=b;M.data[x].e=c;}}void Print(TSMatrix &S){//输出稀疏矩阵int x;int c,b,a[maxsize][maxsize];for(c=1;c<=S.h;c++)for(b=1;b<=S.l;b++)a[c][b]=0;//全部初始化为零for(x=1;x<=S.total;x++){a[S.data[x].i][S.data[x].j]+=S.data[x].e;//在矩阵的相应位置附上非零元素}for(c=1;c<=S.h;c++)for(b=1;b<=S.l;b++){printf("%4d",a[c][b]);if(b==S.l)printf("\");}}void Add(TSMatrix T,TSMatrix V,TSMatrix &M){//加法运算int p=1,q=1;int b=1;if(T.h!=V.h||T.l!=V.l){printf("两矩阵行数或列数不同无法进行相加:\"); exit(0);}while(p<=T.total&&q<=V.total){if(T.data[p].i==V.data[q].i){if(T.data[p].j==V.data[q].j){M.data[b].i=T.data[p].i;M.data[b].e=T.data[p].e+V.data[q].e; p++;b++;q++;}else if(T.data[p].j<v.data[q].j)< p=""> {M.data[b].i=T.data[p].i;M.data[b].j=T.data[p].j;M.data[b].e=T.data[p].e;b++;p++;}else if(T.data[p].j>V.data[q].j){M.data[b].i=V.data[q].i;M.data[b].j=V.data[q].j;M.data[b].e=V.data[q].e;b++;q++;}}else if(T.data[p].i<v.data[q].i)< p=""> {M.data[b].i=T.data[p].i;M.data[b].j=T.data[p].j;M.data[b].e=T.data[p].e;b++;p++;}else if(T.data[p].i>V.data[q].i){M.data[b].i=V.data[q].i;M.data[b].j=V.data[q].j;b++;q++;}}//下面两个循环是把上面循环中未处理的数据添加到M中while(p<=T.total){M.data[b].i=T.data[p].i;M.data[b].j=T.data[p].j;M.data[b].e=T.data[p].e;b++;p++;}while(q<=V.total){M.data[b].i=V.data[q].i;M.data[b].j=V.data[q].j;M.data[b].e=V.data[q].e;b++;q++;}M.h=T.h;M.l=T.l;M.total=b-1; //b最后要减一,因为上面处理最后一个数时b也增加1了}void TransposTSMtrix(TSMatrix A,TSMatrix &B) //完成矩阵的转置,一次快速定位法{int j,t,p,q;int num[maxsize],position[maxsize];//num矩阵某列非零元个数,positionB.h=A.l;B.l=A.h;B.total=A.total;if(B.total){for(j=1;j<=A.l;j++)num[j]=0;for(t=1;t<=A.total;t++)num[A.data[t].j]++;position[1]=1;for(j=2;j<=A.l;j++)position[j]=position[j-1]+num[j-1];for(p=1;p<=A.total;p++){j=A.data[p].j;q=position[j];B.data[q].i=A.data[p].j;B.data[q].j=A.data[p].i;B.data[q].e=A.data[p].e;position[j]++;}}}void Jiansmatrix(TSMatrix M,TSMatrix N,TSMatrix &T){ int m=1,n=1,t=1;if(M.h!=N.h||M.l!=N.l){printf("两矩阵行数或列数不同无法进行相减");exit(0);} T.h=M.h;T.l=M.l;while(m<=M.total&&n<=N.total){{if(M.data[m].i==N.data[n].i)if(M.data[m].j==N.data[n].j){if(M.data[m].e==N.data[n].e){T.data[t].i=M.data[m].i;T.data[t].j=M.data[m].j;m++;n++;}else{T.data[t].e=M.data[m].e-N.data[n].e; T.data[t].i=M.data[m].i;T.data[t].j=M.data[m].j;t++;m++;n++;}}else if(M.data[m].j<n.data[n].j)< p=""> {T.data[t].e=M.data[m].e;T.data[t].i=M.data[m].i;T.data[t].j=M.data[m].j;t++;m++;}else if(M.data[m].j>N.data[n].j){T.data[t].e=0-N.data[n].e;T.data[t].i=N.data[n].i;T.data[t].j=N.data[n].j;t++;n++;}else{if(M.data[m].i<n.data[n].i)< p=""> {T.data[t].i=M.data[m].i;T.data[t].j=M.data[m].j;T.data[t].e=M.data[m].e;t++;m++;}else {T.data[t].e=0-N.data[n].e;T.data[t].i=N.data[n].i;T.data[t].j=N.data[n].j;t++;n++;}}}}while(M.total==(m-1)&&n<=N.total) {T.data[t].i=N.data[n].i;T.data[t].j=N.data[n].j;T.data[t].e=N.data[n].e;t++;n++;}while(N.total==(n-1)&&m<=M.total) {T.data[t].i=M.data[m].i;T.data[t].j=M.data[m].j;T.data[t].e=M.data[m].e;t++;m++;}T.total=t-1;}void Multsmatrix(TSMatrix M,TSMatrix N,TSMatrix &T) { int p,q,Qn=0;int a[200][200];if(M.l!=N.h){printf("两矩阵无法相乘");exit(0);}T.h=M.h;T.l=N.l;for(p=1;p<=M.h;p++)for(q=1;q<=N.l;q++)a[p][q]=0;for(p=1;p<=M.total;p++)for(q=1;q<=N.total;q++)if(M.data[p].j==N.data[q].i){a[M.data[p].i][N.data[q].j]+=M.data[p].e*N.data[q].e;}for(p=1;p<=M.h;p++)for(q=1;q<=N.l;q++)if(a[p][q]!=0){Qn++;T.data[Qn].e=a[p][q];T.data[Qn].i=p;T.data[Qn].j=q;}T.total=Qn;}void main(){TSMatrix ts1,ts2,ts3;int choice;do{printf("1.矩阵的转置!\");printf("2.两个矩阵相加!\");printf("3.两个矩阵相减!\");printf("4.两个矩阵相乘!\");printf("5.退出程序!\");printf("请输入您的选择:\");scanf("%d",&choice);switch(choice){case 1:printf("请输入矩阵的行和列及非零元个数用逗号隔开:\"); Creat(ts1);Print(ts1);TransposTSMtrix(ts1,ts2);printf("转置后的矩阵为:\");Print(ts2);break;case 2:printf("请输入第一个矩阵的行和列及非零元个数用逗号隔开:\"); Creat(ts1);printf("第一个矩阵为:\");Print(ts1);printf("请输入第二个矩阵的行和列及非零元个数用逗号隔开:\"); Creat(ts2);printf("第二个矩阵为:\");Print(ts2);Add(ts1,ts2,ts3);printf("以上两个矩阵相加后为:\");Print(ts3);break;case 3:printf("请输入第一个矩阵的行和列及非零元个数用逗号隔开:\"); Creat(ts1);printf("第一个矩阵为:\");Print(ts1);printf("请输入第二个矩阵的行和列及非零元个数用逗号隔开:\"); Creat(ts2);printf("第二个矩阵为:\");Print(ts2);Jiansmatrix(ts1,ts2,ts3);printf("以上两个矩阵相减后为:\");Print(ts3);break;case 4:printf("请输入第一个矩阵的行和列及非零元个数用逗号隔开:\"); Creat(ts1);printf("第一个矩阵为:\");Print(ts1);printf("请输入第二个矩阵的行和列及非零元个数用逗号隔开:\"); Creat(ts2);printf("第二个矩阵为:\");Print(ts2);Multsmatrix(ts1,ts2,ts3);printf("以上两个矩阵相乘后为:\");Print(ts3);break;case 5:exit(0);break;}}while(choice!=0); scanf("%d",&choice); }</n.data[n].i)<></n.data[n].j)<></v.data[q].i)<></v.data[q].j)<>。
稀疏矩阵(算法与数据结构课程设计)

稀疏矩阵一、问题描述假若在n m ⨯阶中,有t 个元素不为零,令nm t ⨯=δ称为矩阵的稀疏因子。
通常认为≤δ0.05时称为稀疏矩阵。
稀疏矩阵的研究大大的减少了数据在计算机中存储所需的空间,然而,它们的运算却与普通矩阵有所差异。
通过本次实验实现稀疏矩阵的转置、加法和乘法等多种运算。
二、基本要求1、稀疏矩阵采用三元组表示,建立稀疏矩阵,并能按矩阵和三元组方式输出;2、编写算法,完成稀疏矩阵的转置操作;3、编写算法,完成对两个具有相同行列数的稀疏矩阵进行求和操作;4、编写算法,对前一矩阵行数与后一矩阵列数相等的两个矩阵,完成两个稀疏矩阵的相乘操作。
三、测试数据1、转置操作的测试数据:⎪⎪⎪⎪⎪⎭⎫ ⎝⎛00200013000010020100 2、相加操作的测试数据: ⎪⎪⎪⎪⎪⎭⎫ ⎝⎛00200013000010020100 ⎪⎪⎪⎪⎪⎭⎫ ⎝⎛00200010000210030300 3、相乘操作的测试数据: ⎪⎪⎪⎪⎪⎭⎫ ⎝⎛0000000300400021 ⎪⎪⎪⎪⎪⎭⎫ ⎝⎛001002000021 四、算法思想1、三元组结构类型为Triple ,用i 表示元素的行,j 表示元素的列,e 表示元素值。
稀疏矩阵的结构类型为TSMatrix ,用数组data[]表示三元组,mu 表示行数,nu 表示列数,tu 表示非零元个数。
2、稀疏矩阵转置的算法思想将需要转置的矩阵a 所有元素存储在三元组表a.data 中,按照矩阵a 的列序来转置。
为了找到a的每一列中所有非零元素,需要对其三元组表a.data扫描一遍,由于a.data 是以a的行需序为主序来存放每个非零元的,由此得到的就是a的转置矩阵的三元组表,将其储存在b.data中。
3、稀疏矩阵相加的算法思想比较满足条件(行数及列数都相同的两个矩阵)的两个稀疏矩阵中不为0的元素的行数及列数(即i与j),将i与j都相等的前后两个元素值e相加,保持i,j不变储存在新的三元组中,不等的则分别储存在此新三元组中。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
稀疏矩阵应用摘要本课程设计主要实现在三元组存储结构与十字链表存储结构下输入稀疏矩阵,并对稀疏矩阵进行转置,相加,相乘操作,最后输出运算后的结果。
在程序设计中,考虑到方法的难易程度,采用了先用三元组实现稀疏矩阵的输入,输出,及其转置,相加,相乘操作的方法,再在十字链表下实现。
程序通过调试运行,结果与预期一样,初步实现了设计目标。
关键词程序设计;稀疏矩阵;三元组;十字链表1 引言1.1课程设计任务本课程设计主要实现在三元组存储结构与十字链表存储结构下输入稀疏矩阵,并对稀疏矩阵进行转置,相加,相乘操作,最后输出运算后的结果。
稀疏矩阵采用三元组和十字链表表示,并在两种不同的存储结构下,求两个具有相同行列数的稀疏矩阵A和B的相加矩阵C,并输出C;求出A的转置矩阵D,输出D;求两个稀疏矩阵A和B的相乘矩阵E,并输出E。
1.2课程设计性质数据结构课程设计是重要地实践性教学环节。
在进行了程序设计语言课和《数据结构》课程教学的基础上,设计实现相关的数据结构经典问题,有助于加深对数据结构课程的认识。
本课程设计是数据结构中的一个关于稀疏矩阵的算法的实现,包括在三元组和十字链表下存储稀疏矩阵,并对输入的稀疏矩阵进行转置,相加,相乘等操作,最后把运算结果输出。
此课程设计要求对数组存储结构和链表存储结构非常熟悉,并能熟练使用它们。
1.3课程设计目的其目的是让我们在学习完C、数据结构等课程基础上,掌握多维数组的逻辑结构和存储结构、掌握稀疏矩阵的压缩存储及转置,相加,相乘等基本操作,并用不同的方法输出结果,进一步掌握设计、实现较大系统的完整过程,包括系统分析、编码设计、系统集成、以及调试分析,熟练掌握数据结构的选择、设计、实现以及操作方法,为进一步的应用开发打好基础。
2需求分析2.1设计函数建立稀疏矩阵及初始化值和输出稀疏矩阵的值本模块要求设计函数建立稀疏矩阵并初始化,包括在三元组结构下和十字链表结构下。
首先要定义两种不同的结构体类型,在创建稀疏矩阵时,需要设计两个不同的函数分别在三元组和十字链表下创建稀疏矩阵,在输入出现错误时,能够对错误进行判别处理,初始化稀疏矩阵都为空值,特别注意在十字链表下,对变量进行动态的地址分配。
在设计输出稀疏矩阵的值的函数时,也要针对两种不同的情况,分别编制函数,才能准确的输出稀疏矩阵。
在对稀疏矩阵进行初始化及输出值时,均只输出非零元素的值和它所在的所在行及所在列。
2.2构造函数进行稀疏矩阵的转置并输出结果本模块要求设计函数进行稀疏矩阵的转置并输出转置后的结果,由于对稀疏函数的转置只对一个矩阵进行操作,所以实现起来难度不是很大,函数也比较容易编写。
在编写函数时,要先定义一个相应的结构体变量用于存放转置后的矩阵,最后把此矩阵输出。
2.3构造函数进行两个稀疏矩阵相加及相乘并输出最终的稀疏矩阵本模块要求设计相加和相乘函数对两个矩阵进行运算,并输出最终的稀疏矩阵,在进行运算前,要对两个矩阵进行检查,看是不是相同类型的矩阵,因为两个矩阵相加要求两个矩阵一定是同一类型的矩阵,定义相应的矩阵类型用于存放两个矩阵相加相乘后的结果矩阵,这个结果矩阵的行数列数需要综合多方面情况来确定。
这四个函数也是整个程序的难点,需要灵活运用数组及指针的特点。
2.4退出系统本模块要求设置选项能随时结束程序的运行,本程序中采用exit(0)函数。
程序以用户和计算机的对话方式执行,即在计算机终端上显示“提示信息”之后,由用户在键盘上输入演示程序中需要的相关信息及命令。
3概要设计3.1主界面设计为了实现在两种存储结构下对稀疏矩阵的多种算法功能的管理,首先设计一个含有多个菜单项的主控菜单子程序以链接系统的各项子功能,方便用户交互式使用本系统。
本系统主控菜单运行界面如图1所示。
图1主界面图3.2存储结构设计本系统采用三元组结构和十字链表结构存储稀疏矩阵的具体信息。
其中:在三元组中,所有元素的信息用数组表示,每个数组元素中包含有行下标(i),列下标(j)和对应的数值(e),它们是整型数据,全部的信息用在十字链表中,全部结点的信息用结构体(TSMatrix)包含,包括用数组(Triple data[MAXSIZE])和总共的行数(mu),列数(nu)以及非零元素的个数(tu)。
在十字链表下,头结点为指针数组的十字链表存储;每个结点里面包含行下标(i),列下标(j)和对应的数值(e),它们是整型数据,还有两个指针(right)、(down),属于OLNode结构体。
全部的信息用结构体(crosslist)包含,包括指针数组(OLink* rhead 和*chead)和总共的行数(mu),列数(nu)以及非零元素的个数(tu)。
三元组结构体定义:typedef struct{int i,j;int e;}Triple;typedef struct{Triple data[MAXSIZE];int rpos[MAXSIZE + 1];int nu,mu,tu;}TSMatrix;十字链表结构体定义:typedef struct OLNode{int i,j;int e;struct OLNode *right,*down;}OLNode,*OLink;typedef struct {int mu,nu,tu;OLink *rhead,*chead;}CrossList;3.3系统功能设计本系统除了要完成分别在三元组存储结构以及在十字链表下实现稀疏矩阵的初始化功能外还设置了4个子功能菜单。
稀疏矩阵的建立及初始化在三元组存储结构下,由函数void CreateSMatrix(TSMatrix&M)实现,在十字链表存储结构下,由函数void CreateSMatix_OL(CrossList&M)依据读入的行数和列数以及非零元素的个数,分别设定每个非零元素的信息。
4个子功能的设计描述如下。
(1)稀疏矩阵的转置:此功能在三元组存储结构下,由函数void TransposeSMatrix(TSMatrix M,TSMatrix &T)实现,在十字链表存储结构下,由函数void TurnSMatrix_OL(CrossList &M)实现。
当用户选择该功能,系统提示用户初始化一个矩阵,然后进行转置,最终输出结果。
(2)稀疏矩阵的加法:此功能在三元组存储结构下,由函数void AddTMatix(TSMatrix M,TSMatrix T,TSMatrix &S)实现,在十字链表存储结构下,由函数int SMatrix_ADD(CrossList *A,CrossList *B)实现。
当用户选择该功能,系统即提示用户初始化要进行加法的两个矩阵的信息。
然后进行加法,最后输出结果。
(3)稀疏矩阵的乘法:此功能在三元组存储结构下,由函数int MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q)实现。
在十字链表存储结构下,由函数int MultSMatrix_OL(CrossList M,CrossList N, CrossList &Q)实现。
当用户选择该功能,系统提示输入要进行相乘的两个矩阵的详细信息。
然后进行相乘,最后得到结果。
(4)退出:即退出稀疏矩阵的应用系统,由exit(0)函数实现。
当用户选择该功能,则退出该稀疏矩阵的应用系统。
4 详细设计4.1 数据类型定义三元组结构体定义:typedef struct{ //三元组结构体int i,j; //行标、列表int e; //值}Triple;typedef struct{Triple data[MAXSIZE]; //三元组表int rpos[MAXSIZE + 1];int nu,mu,tu; //行数、列数、非零元个数}TSMatrix;十字链表结构体定义:typedef struct OLNode{ //结点结构int i,j; //行标、列标int e; //值struct OLNode *right,*down; //同一行、列的下一个结点}OLNode,*OLink;typedef struct {int mu,nu,tu; //行数、列数、非零元个数OLink *rhead,*chead; //行、列指针基指}CrossList;4.2系统主要子程序详细设计A. 主程序模块设计:void main(){int n,i;TSMatrix M,T,S; //声明三个三元组数组CrossList MM,TT,SS; //声明三个十字链表printf(" ***稀疏矩阵应用***");printf("\n请你选择创建稀疏矩阵的方法:\n1:用三元组创建稀疏矩阵\n2:用十字链表创建稀疏矩阵\n3:退出程序");printf("\n");scanf("%d",&n);switch(n){case1:CreateSMatrix(M); //创建三元组矩阵printf("您输入的稀疏矩阵为(只列出非零元素):\n 行列大小\n");ShowTMatrix(M); //显示三元组矩阵printf("已经选择三元组创建稀疏矩阵,请选择操作:\n1:稀疏矩阵转置\n2:稀疏矩阵相加\n3:稀疏矩阵相乘\n4:退出程序\n");scanf("%d",&i);switch(i){case1:TransposeSMatrix(M,T); //对三元组矩阵进行转置printf("转置后的矩阵为(只列出非零元素):\n 行列大小\n");ShowTMatrix(T);break;case2:printf("请你输入另一个稀疏矩阵:");CreateSMatrix(T);AddTMatix(M,T,S); //两个三元组矩阵相加printf("相加后的矩阵为(只列出非零元素):\n 行列大小\n");ShowTMatrix(S);break;case3:printf("请你输入另一个稀疏矩阵:");CreateSMatrix(T);MultSMatrix(M,T,S); //两个三元组矩阵相乘printf("相乘后的矩阵为(只列出非零元素):\n 行列大小\n");ShowTMatrix(S);break;case4:exit(0);};break;case2:{CreateSMatix_OL(MM); //创建十字链表矩阵printf("您输入的稀疏矩阵为(只列出非零元素):\n 行列大小\n");ShowMAtrix(&MM); //显示十字链表矩阵printf("已经选择十字链表创建稀疏矩阵,请选择操作: 1:稀疏矩阵转置\n 2:稀疏矩阵相加\n 3:稀疏矩阵相乘\n 4:退出程序\n");scanf("%d",&i);switch(i){case1:TurnSMatrix_OL(MM); //十字链表矩阵转置printf("转置后的矩阵为(只列出非零元素):\n 行列大小\n");ShowMAtrix(&MM);break;case2:printf("请你输入另一个稀疏矩阵:");CreateSMatix_OL(TT);SMatrix_ADD(&MM,&TT); //两个十字链表矩阵相加printf("相加后的矩阵为(只列出非零元素):\n 行列大小\n"); ShowMAtrix(&MM);break;case3:printf("请你输入另一个稀疏矩阵:");CreateSMatix_OL(TT);MultSMatrix_OL(MM,TT,SS); //两个十字链表矩阵相乘printf("相乘后的矩阵为(只列出非零元素):\n 行列大小\n");ShowMAtrix(&SS);break;case4:exit(0);}};break;case3:exit(0);default :printf("erorr");}}B. 稀疏矩阵操作各子函数的定义:(1)建立与初始化稀疏矩阵:void CreateSMatrix(TSMatrix &M){//采用三元组顺序表存储表示,创建稀疏矩阵Mprintf("请输入稀疏矩阵的行数、列数和非零元个数:");scanf("%d%d%d",&M.mu,&M.nu,&M.tu);if((M.mu<=0)||(M.nu<=0)||(M.tu<=0)||(M.tu>M.mu*M.nu))//判断行值、列值、元素个数是否合法printf("输入有误!");for(int i=1;i<=M.tu;i++){//输入稀疏矩阵元素printf("请输入元素坐标(所在行,所在列)及大小:");scanf("%d%d%d",&M.data[i].i,&M.data[i].j,&M.data[i].e);if((M.data[i].i<=0)||(M.data[i].j<=0)){printf("输入错误,请重新输入");scanf("%d%d%d",&M.data[i].i,&M.data[i].j,&M.data[i].e);}}int num[100];if(M.tu){int i;for(i = 1; i <= M.mu; i++) num[i] = 0;//初始化for(int t = 1; t <= M.tu; t++) ++num[M.data[t].i];//求M中每一行含非零元素个数//求rposM.rpos[1] = 1;for(i = 2; i <= M.mu; i++) M.rpos[i] = M.rpos[i-1] + num[i-1];}} //创建三元组int CreateSMatix_OL(CrossList &M){int i,j,e;OLink q;OLink p;printf("请输入稀疏矩阵的行数,列数,非零元素的个数"); //矩阵行数,列数下标均从开始;scanf("%d%d%d",&M.mu,&M.nu,&M.tu);M.rhead=(OLink *)malloc((M.mu+1)*sizeof(OLNode));//分配内存空间M.chead=(OLink *)malloc((M.nu+1)*sizeof(OLNode));//分配内存空间for( i=1;i<=M.mu;i++)M.rhead[i]=NULL;//把矩阵每个元素置空值for( i=1;i<=M.nu;i++)M.chead[i]=NULL;printf("请输入稀疏矩阵,如果行为,则退出\n");scanf("%d%d%d",&i,&j,&e);while(i!=0){p=(OLink)malloc(sizeof(OLNode));p->i=i;p->j=j;p->e=e;if(M.rhead[i]==NULL||M.rhead[i]->j>j){p->right=M.rhead[i];M.rhead[i]=p;} else{q=M.rhead[i];while(q->right&&q->right->j<j)q=q->right;p->right=q->right;q->right=p;}if(M.chead[j]==NULL||M.chead[j]->i>i){p->down=M.chead[j];M.chead[j]=p;} else{q=M.chead[j];while(q->down&&q->down->i<i)q=q->down;p->down=q->down;q->down=p;}scanf("%d%d%d",&i,&j,&e);}return1;}//创建十字链表(2)输出稀疏矩阵:void ShowTMatrix(TSMatrix M){for(int col=1;col<=M.mu;col++)//通过双重循环,把稀疏矩阵中不为零的元素的行数、列数和值显示出来for(int p=1;p<=M.tu;p++)if(M.data[p].i==col)printf("%4d %4d %4d\n",M.data[p].i,M.data[p].j,M.data[p].e);}//三元组显示int ShowMAtrix(CrossList *A){int col;OLink p;for(col=1;col<=A->mu;col++)if(A->rhead[col]){p=A->rhead[col];//通过循环,把A结点的rhead[col]赋给pwhile(p){printf("%3d%3d%3d\n",p->i,p->j,p->e);p=p->right;}}return1;}//十字链表显示(3)实现矩阵的转置:void TransposeSMatrix(TSMatrix M,TSMatrix &T){T.nu=M.mu;//T矩阵存放转置后的矩阵T.mu=M.nu;T.tu=M.tu;int q=1;for(int col=1;col<=M.nu;col++)//通过循环,把非零元素的行数与列数进行交换,实现转置for(int 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 TurnSMatrix_OL(CrossList &M){int col,row; //定义循环变量OLink p,q; //定义OLink结构类型变量for(col=1;col<=M.mu;col++) //通过循环,把非零元素的行数与列数进行交换,实现转置{ q=p=M.rhead[col];while(q){row=p->i;p->i=p->j;p->j=row;q=p->right;p->right=p->down;p->down=q;}}}//十字链表转置(4)实现两个矩阵的相加:void AddTMatix(TSMatrix M,TSMatrix T,TSMatrix &S){//矩阵S存放相加后的矩阵S.mu=M.mu>T.mu?M.mu:T.mu;//对S矩阵的行数赋值S.nu=M.nu>T.nu?M.nu:T.nu;//对S矩阵的列数赋值S.tu=0;int ce;int q=1;int mcount=1,tcount=1;while(mcount<=M.tu&&tcount<=T.tu){switch(Compare(M.data[mcount].i,M.data[mcount].j,T.data[tcount].i,T.data[tcount] .j))//用switch分支语句,用compare函数对需要相加的两个矩阵的某元素行数列数进行比较{case -1: S.data[q].e=M.data[mcount].e;//当M.data[mcount].i<T.data[tcount].i或M.data[mcount].j<T.data[tcount].jS.data[q].i=M.data[mcount].i;S.data[q].j=M.data[mcount].j;//把第一个矩阵的行数i,列数j赋值给S矩阵的行数i,列数jq++;mcount++;break;case1: S.data[q].e=T.data[tcount].e;//当M.data[mcount].i>T.data[tcount].i或M.data[mcount].j>T.data[tcount].jS.data[q].i=T.data[tcount].i;S.data[q].j=T.data[tcount].j;//把第二个矩阵的行数i,列数j赋值给S矩阵的行数i,列数jq++;tcount++;break;case0: ce=M.data[mcount].e+T.data[tcount].e;//其他情况下把两个矩阵的值相加if(ce){ S.data[q].e=ce;S.data[q].i=M.data[mcount].i;S.data[q].j=M.data[mcount].j;q++;mcount++;tcount++;}else {mcount++;tcount++;}break;}}while(mcount<=M.tu){S.data[q].e=M.data[mcount].e;S.data[q].i=M.data[mcount].i;S.data[q].j=M.data[mcount].j;q++;mcount++; }//在case=-1的情况下对S矩阵的非零值,行数,列数进行赋值while(tcount<=M.tu){S.data[q].e=T.data[tcount].e;S.data[q].i=T.data[tcount].i;S.data[q].j=T.data[tcount].j;q++;tcount++;}//在case=1的情况下对S矩阵的非零值,行数,列数进行赋值S.tu=q-1;}//三元组相加int SMatrix_ADD(CrossList *A,CrossList *B){OLNode *pa,*pb,*pre,*p,*cp[100]; //定义OLNode类型的变量int i,j,t;t=A->tu+B->tu;for(j=1;j<=A->nu;j++)cp[j]=A->chead[j];//将A矩阵的列表头指针赋给cp数组for(i=1;i<=A->mu;i++){pa=A->rhead[i];pb=B->rhead[i];//将A,B矩阵的行表头指针分别赋给pa,pbpre=NULL;while(pb){//当pb不等于零if(pa==NULL||pa->j>pb->j){p=(OLink)malloc(sizeof(OLNode));//给p动态分配空间if(!pre)A->rhead[i]=p;else pre->right=p;p->right=pa;pre=p;p->i=i;p->j=pb->j;p->e=pb->e;if(!A->chead[p->j]){A->chead[p->j]=cp[p->j]=p;p->down=NULL;}//如果A->chead[p->j]不等于零,则把p赋给它及cp[p->j]else{cp[p->j]->down=p;cp[p->j]=p;}pb=pb->right;}//否则把p赋给cp[p->j]else if(pa->j<pb->j){pre=pa;pa=pa->right;}else if(pa->e+pb->e){t--;pa->e+=pb->e;pre=pa;pa=pa->right;pb=pb->right;}else { t=t-2;if(!pre)A->rhead[i]=pa->right;else pre->right=pa->right;p=pa;pa=pa->right;if(A->chead[p->j]==p)A->chead[p->j]=cp[p->j]=p->down;else cp[p->j]->down=p->down;free(p);pb=pb->right;}}}A->mu=A->mu>B->mu?A->mu:B->mu;A->nu=A->nu>B->nu?A->nu:B->nu;//A的行与列为A及B当中较大的一个return1;}//十字链表相加(5)实现两个矩阵的相乘:int MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q){int arow, brow, ccol, i, t, ctemp[100], p, q, tp;//定义相乘函数中所需要用到的变量if(M.nu != N.mu) return0;//如果第一个矩阵的行数不等于第二个矩阵的列数,则退出Q.mu = M.mu, Q.nu = N.nu, Q.tu = 0;//三元组结构类型Q存放相乘后的结果if(M.tu * N.tu != 0)//如果两个矩阵元素相乘不为零,则进行运算{for(arow = 1; arow <= M.mu; ++arow);//最外侧循环以矩阵行数作为循环变量{for(i = 0; i <= N.nu; ++i) ctemp[i] = 0;Q.rpos[arow] = Q.tu + 1;if(arow < M.mu) tp = M.rpos[arow + 1];else tp = M.tu +1;for(p = M.rpos[arow]; p < tp; ++p)//把每行与每列相乘{brow = M.data[p].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) return1;Q.data[Q.tu].i = arow, Q.data[Q.tu].j = ccol, Q.data[Q.tu].e = ctemp[ccol];}}}}return1;}//三元组相乘int MultSMatrix_OL(CrossList M, CrossList N, CrossList &Q){int i, j, e; //中间变量OLink p0, q0, p, pl, pla; //中间变量if(M.nu != N.mu) //检查稀疏矩阵M的列数和N的行数是否对应相等{printf ( "稀疏矩阵A的列数和B的行数不相等,不能相乘。