/*
*任务描述:针对稀疏矩阵,实现10个基本操作
*   1:建立稀疏矩阵 ;
*   2:输出稀疏矩阵 ;
*   3:转置稀疏矩阵 ;
*   4:稀疏矩阵相加 ;
*   5:稀疏矩阵相减;
*   6:稀疏矩阵相乘 ;
主要函数:
*   1.void CreateMatrix(Matrix &M);//创建矩阵
*   2.void Output(Matrix M);//输出矩阵
*   3.void TransposeMatrix1(Matrix &M);//转置矩阵算法1
*   4.void TransposeMatrix2(Matrix &M);//转置矩阵算法2
*   5.void TransposeMatrix3(Matrix &M);//转置矩阵算法3
*   6.void AddMatrix(Matrix &M1,Matrix &M2);//矩阵相加
*   7.void SubtractMatrix(Matrix &M1,Matrix &M2);//矩阵相减
*   8.void MultiplyMatrix(Matrix &M,Matrix &N);//矩阵相乘
*   9.Status Check(Matrix M,int index,int row,int line);//检查矩阵M的数组data中第index个元素的行列数
*   10.void SortByRow(Matrix &M);//行优先冒泡排序
*   11.void SortByLine(Matrix &M);//列优先冒泡排序
*/
#include<iostream>
#include<algorithm>
#include<cstring>
#include<iomanip>using namespace std;#define OK 1
#define FALSE 0
#define MAXSIZE 10000typedef int ElemType;
typedef int Status;typedef struct
{int row;//非零元素所在的行int line;//非零元素所在的列ElemType elem;//非零元素大小
} Triple;//非零元素的三元组类型typedef struct
{Triple data[MAXSIZE];//非零元素数组int rownum;//矩阵的行数int linenum;//矩阵的列数int elemnum;//矩阵的非零元素总数
} Matrix;//矩阵类型void CreateMatrix(Matrix &M);//创建矩阵
void Output(Matrix M);//输出矩阵
void TransposeMatrix1(Matrix &M);//转置矩阵算法1
void TransposeMatrix2(Matrix &M);//转置矩阵算法2
void TransposeMatrix3(Matrix &M);//转置矩阵算法3
void AddMatrix(Matrix &M1,Matrix &M2);//矩阵相加
void SubtractMatrix(Matrix &M1,Matrix &M2);//矩阵相减
void MultiplyMatrix(Matrix &M,Matrix &N);//矩阵相乘
Status Check(Matrix M,int index,int row,int line);//检查矩阵M的数组data中第index个元素的行列数
void SortByRow(Matrix &M);//行优先冒泡排序
void SortByLine(Matrix &M);//列优先冒泡排序
void Interaction();//输出操作int main()
{Interaction();Matrix M,N;int operate;while(cin>>operate){switch(operate){case 0:return 0;case 1:cout<<"请输入创建的稀疏矩阵的行数、列数、非0元素个数:";cin>>M.rownum>>M.linenum>>M.elemnum;CreateMatrix(M);break;case 2:Output(M);break;case 3:cout<<"转置矩阵共3种方法,请输入使用的方法序号(1/2/3):";cin>>operate;switch(operate){case 1:TransposeMatrix1(M);break;case 2:TransposeMatrix2(M);break;case 3:TransposeMatrix3(M);break;}break;case 4:
INPUT1:cout<<"请输入创建的稀疏矩阵的行数、列数、非0元素个数:";cin>>N.rownum>>N.linenum>>N.elemnum;if(M.rownum!=N.rownum||M.linenum!=N.linenum){cout<<"矩阵相加的前提是两个矩阵的行数列数分别相等。请创建合法的矩阵。\n";goto INPUT1;}CreateMatrix(N);AddMatrix(M,N);break;case 5:
INPUT2:cout<<"请输入创建的稀疏矩阵的行数、列数、非0元素个数:";cin>>N.rownum>>N.linenum>>N.elemnum;if(M.rownum!=N.rownum||M.linenum!=N.linenum){cout<<"矩阵相减的前提是两个矩阵的行数列数分别相等。请创建合法的矩阵。\n";goto INPUT2;}CreateMatrix(N);SubtractMatrix(M,N);break;case 6:
INPUT3:cout<<"请输入创建的稀疏矩阵的行数、列数、非0元素个数:";cin>>N.rownum>>N.linenum>>N.elemnum;if(M.linenum!=N.rownum){cout<<"矩阵相乘的前提是矩阵1的列数等于矩阵2的行数。请创建合法的矩阵。\n";goto INPUT3;}CreateMatrix(N);MultiplyMatrix(M,N);break;default:cout<<"请输入正确的操作数字!\n";}}return 0;
}void CreateMatrix(Matrix &M)//创建矩阵
{cout<<"请输入"<<M.elemnum<<"个非0元素的行数、列数(均从1开始)、元素大小:\n";for(int i=1; i<=M.elemnum; i++){cin>>M.data[i].row>>M.data[i].line>>M.data[i].elem;}SortByRow(M);//将矩阵的所有非零元素按照行优先的顺序重新排列,便于后续操作cout<<"创建的稀疏矩阵为:\n";Output(M);
}void Output(Matrix M)//输出矩阵
{int index=1;for(int row=1; row<=M.rownum; row++){for(int line=1; line<=M.linenum; line++){if(Check(M,index,row,line))//检测当前位置是否是非零元素{cout<<setw(4)<<M.data[index].elem;index++;}else{cout<<setw(4)<<0;}}cout<<endl;}
}void TransposeMatrix1(Matrix &M)//转置矩阵算法1
{//算法描述:因为当前矩阵是行优先的,转置后变成列优先的(相对未转置前)。因此//枚举列数1——M.linenum,对于每一个列数line,按照原矩阵的顺序遍历一遍所有的非零元素,//找出列数等于line的非零元素并完成转置该元素。Matrix T;T.rownum=M.linenum;T.linenum=M.rownum;T.elemnum=M.elemnum;if(T.elemnum){int index1=1;for(int line=1; line<=M.linenum; line++)//枚举列数1——M.linenum{for(int index2=1; index2<=M.elemnum; index2++)//遍历一遍所有的非零元素{if(M.data[index2].line==line)//找出列数等于line的非零元素{//转置该元素T.data[index1].row=M.data[index2].line;T.data[index1].line=M.data[index2].row;T.data[index1].elem=M.data[index2].elem;index1++;}}}}M=T;//交接矩阵cout<<"转置后的稀疏矩阵为:\n";Output(M);
}void TransposeMatrix2(Matrix &M)//转置矩阵算法2
{//算法描述:增加两个数组:num[M.linenum+1]与cpot[M.linenum+1]//num[line]:矩阵M第line列中非零元素的总个数;//cpot[line]:M中第line列当前非零元素在M.data[]中的下标(初始化为当前列中第一个非零元素的下标)//遍历一遍原矩阵,对当前遍历到的第index个元素,cpot[M.data[index].line]即为该元素在转置后的矩阵中//data数组中的下标,一步定位。Matrix T;T.rownum=M.linenum;T.linenum=M.rownum;T.elemnum=M.elemnum;if(T.elemnum){int num[M.linenum+1];memset(num,0,sizeof(num));//初始化num数组for(int index=1; index<=M.elemnum; index++)//求num数组{num[M.data[index].line]++;}int cpot[M.linenum+1];int index=0;while(num[++index]==0);cpot[index]=1;//第一个该列中存在非零元素的列数在cpot中的值为1for(int index2=index+1; index2<=M.linenum; index2++)//递推求cpot数组{cpot[index2]=cpot[index2-1]+num[index2-1];}for(index=1; index<=M.elemnum; index++){int line=M.data[index].line;int index1=cpot[line];//直接定位当前元素转置后在新矩阵data数组中的下标T.data[index1].row=M.data[index].line;T.data[index1].line=M.data[index].row;T.data[index1].elem=M.data[index].elem;cpot[line]++;//更新指示的位置}}M=T;cout<<"转置后的稀疏矩阵为:\n";Output(M);
}void TransposeMatrix3(Matrix &M)//转置矩阵算法3
{//算法描述:不需要开辟新数组的内存,直接按照列优先的原则对//原矩阵的所有非零元素进行冒泡排序。排序后,对矩阵所有非零元素//交换行列数,即完成转置。SortByLine(M);//列优先排序for(int index=1; index<=M.elemnum; index++){swap(M.data[index].line,M.data[index].row);//交换行列数}swap(M.linenum,M.rownum);cout<<"转置后的稀疏矩阵为:\n";Output(M);
}void AddMatrix(Matrix &M1,Matrix &M2)//矩阵相加
{Matrix M;M.rownum=M1.rownum;M.linenum=M1.linenum;int index1=1,index2=1,index=1;for(int row=1; row<=M.rownum; row++){for(int line=1; line<=M.linenum; line++){if(Check(M1,index1,row,line)&&Check(M2,index2,row,line)){M.data[index].elem=M1.data[index1].elem+M2.data[index2].elem;M.data[index].row=row;M.data[index].line=line;index1++;index2++;index++;}else if(Check(M1,index1,row,line)&&!Check(M2,index2,row,line)){M.data[index].elem=M1.data[index1].elem;M.data[index].row=row;M.data[index].line=line;index1++;index++;}else if(!Check(M1,index1,row,line)&&Check(M2,index2,row,line)){M.data[index].elem=M2.data[index2].elem;M.data[index].row=row;M.data[index].line=line;index2++;index++;}}}M.elemnum=index-1;M1=M;Output(M);cout<<"相加后的矩阵是:\n";Output(M1);
}void SubtractMatrix(Matrix &M1,Matrix &M2)//矩阵相减
{Matrix M;M.rownum=M1.rownum;M.linenum=M1.linenum;int index1=1,index2=1,index=1;for(int row=1; row<=M.rownum; row++){for(int line=1; line<=M.linenum; line++){if(Check(M1,index1,row,line)&&Check(M2,index2,row,line)){M.data[index].elem=M1.data[index1].elem-M2.data[index2].elem;M.data[index].row=row;M.data[index].line=line;index1++;index2++;index++;}else if(Check(M1,index1,row,line)&&!Check(M2,index2,row,line)){M.data[index].elem=M1.data[index1].elem;M.data[index].row=row;M.data[index].line=line;index1++;index++;}else if(!Check(M1,index1,row,line)&&Check(M2,index2,row,line)){M.data[index].elem=-M2.data[index2].elem;//此处变为其相反数M.data[index].row=row;M.data[index].line=line;index2++;index++;}}}M.elemnum=index-1;M1=M;cout<<"相减后的矩阵是:\n";Output(M1);
}void MultiplyMatrix(Matrix &M,Matrix &N)//矩阵相乘
{//算法描述:先对矩阵N进行列优先排序(M已经为行优先);// 在结果矩阵Q可能存在非零元素的情况下://枚举Q的每一行row,每一列line,设Q在(row,line)处的值为temp,//在(row,line)下枚举矩阵M中行数等于row的所有元素M.data[index1]//在每个M.data[index1]下,枚举列数等于line的矩阵N 中的所有元素N.data[index3],//对每个N.data[index3],当N.data[index3].row等于M.data[index1].line时,两个元素位置匹配相乘即可,//累加到temp上(temp=temp+N.data[index3].elem*M.data[index1].elem);//当前行列(row,line)遍历完成后,temp的值即可求出。//使用了四个下标:index1,index2,index3,index4//2和4是辅助更新的下标,详见程序。  9SortByLine(N);//对矩阵N进行列优先排序Matrix Q;Q.rownum=M.rownum;Q.linenum=N.linenum;Q.elemnum=0;int index=1;if(M.elemnum*N.elemnum){int index1,index2=1;//index1是矩阵M的遍历器;//index2辅助更新M矩阵元素遍历起点,其值为矩阵M中第一个行数等于当前row的元素下标for(int row=1; row<=Q.rownum; row++)//枚举Q的每一行row{int index3,index4=1;//index3是矩阵N的遍历器;//index4辅助更新N矩阵元素遍历起点,其值为矩阵N中第一个列数等于当前line的元素下标for(int line=1; line<=Q.linenum; line++)//每一列line{int temp=0;//Q在(row,line)处的值for(index1=index2; index1<=M.elemnum&&M.data[index1].row==row; index1++)//在index1不越界且M的第index1个元素在第row行的前提下遍历M的元素{for(index3=index4; index3<=N.elemnum&&N.data[index3].line==line; index3++)//在index3不越界且N的第index3个元素在第line列的前提下遍历N的元素{if(M.data[index1].line==N.data[index3].row)//两个元素位置匹配相乘即可{temp=temp+M.data[index1].elem*N.data[index3].elem;//累加到temp上}}if(index1==M.elemnum||M.data[index1+1].row!=row)//当矩阵M的所有在第row行的元素遍历完成一遍后(index1==M.elemnum针对矩阵M的最后一行){index4=index3;//此时N.data[index3].line=line+1,将该下标值复制到index4中,下次遍历下一列时无需从头开始}}if(temp){Q.data[index].row=row;Q.data[index].line=line;Q.data[index].elem=temp;index++;}if(line==Q.linenum)//当矩阵Q的第row行求值完成后{index2=index1;//此时M.data[index1].row=row+1,将该下标值复制到index2中,下次遍历下一行时无需从头开始}}}Q.elemnum=index-1;}M=Q;cout<<"相乘后的稀疏矩阵为:\n";Output(M);
}Status Check(Matrix M,int index,int row,int line)//检查矩阵M的数组data中第index个元素的行列数
{if(index<=M.elemnum&&M.data[index].row==row&&M.data[index].line==line){return OK;}return FALSE;
}void SortByRow(Matrix &M)//行优先冒泡排序
{if(M.elemnum){for(int i=1; i<=M.elemnum; i++){for(int j=i+1; j<=M.elemnum; j++){if(M.data[i].row>M.data[j].row||(M.data[i].row==M.data[j].row&&M.data[i].line>M.data[j].line)){swap(M.data[i],M.data[j]);}}}}
}void SortByLine(Matrix &M)//列优先冒泡排序
{if(M.elemnum){for(int i=1; i<=M.elemnum; i++){for(int j=i+1; j<=M.elemnum; j++){if(M.data[i].line>M.data[j].line||(M.data[i].line==M.data[j].line&&M.data[i].row>M.data[j].row)){swap(M.data[i],M.data[j]);}}}}
}void Interaction()//输出操作
{cout<<"请输入对应操作的序号:\n";cout<<"0:退出程序 ;\n";cout<<"1:建立稀疏矩阵 ;\n";cout<<"2:输出稀疏矩阵 ;\n";cout<<"3:转置稀疏矩阵 ;\n";cout<<"4:稀疏矩阵相加 ;\n";cout<<"5:稀疏矩阵相减;\n";cout<<"6:稀疏矩阵相乘 ;\n";
}

稀疏矩阵(三元组顺序表存储)6种操作的实现相关推荐

  1. 数据结构 稀疏矩阵三元组顺序表 基本操作

    [数据结构]稀疏矩阵 三元组顺序表存储 基本操作 1.稀疏矩阵定义: 假设在 mn 的矩阵中,又t个元素不为零.δ = t/mn ,称δ为矩阵的稀疏因子,通常定义δ小于等于0.05时称为稀疏矩阵. 2 ...

  2. 稀疏矩阵的三元组顺序表存储表示及基本操作

    /* Name: 稀疏矩阵的三元组顺序表存储表示及基本操作 Copyright:  Author: 巧若拙  Date: 27-10-14 21:28 Description:  ---------- ...

  3. 稀疏矩阵的三元组存储方法c语言,数据结构C语言版 稀疏矩阵的三元组顺序表存储表示和实现...

    陈独秀的秘密 数据结构C语言版 稀疏矩阵的三元组顺序表存储表示和实现 P98 编译环境:Dev-C++ 4.9.9.2 日期:2011年2月8日 */ typedef int ElemType; // ...

  4. 数组:矩阵快速转置 矩阵相加 三元组顺序表/三元矩阵 随机生成稀疏矩阵 压缩矩阵【C语言,数据结构】(内含源代码)

    目录 题目: 题目分析: 概要设计: 二维矩阵数据结构: 三元数组\三元顺序表顺序表结构: 详细设计: 三元矩阵相加: 三元矩阵快速转置: 调试分析: 用户手册: 测试结果: 源代码: 主程序: 头文 ...

  5. 2021-10-28 三元组顺序表表示的稀疏矩阵加法

    PTA练习题--稀疏矩阵的加法. 题目分析:此题的核心在于找到行数和列数相等的元素进行求和,若和为零时则舍去,当行数/列数不等时分类进行讨论. 此题共分为七种情况进行讨论,分别为: 1 ai=bi:a ...

  6. c语言三元组作用,三元组顺序表,稀疏矩阵的三元组表示及(C语言)实现

    本节介绍稀疏矩阵的三元组顺序表压缩存储方式. 通过<矩阵的压缩存储>一节我们知道,稀疏矩阵的压缩存储,至少需要存储以下信息: 矩阵中各非 0 元素的值,以及所在矩阵中的行标和列标: 矩阵的 ...

  7. 三元组顺序表表示的稀疏矩阵转置(10分)

    三元组顺序表表示的稀疏矩阵转置(10分) 本题要求实现一个函数,实现三元组顺序表表示的稀疏矩阵转置. 函数接口定义: struct tripletable * trans(struct triplet ...

  8. 三元组顺序表表示的稀疏矩阵加法

    三元组顺序表表示的稀疏矩阵加法. 输入格式: 输入第1行为两个同型矩阵的行数m.列数n,矩阵A的非零元素个数t1,矩阵B的非零元素个数t2. 按行优先顺序依次输入矩阵A三元组数据,共t1行,每行3个数 ...

  9. 《数据结构》实验报告(一)——顺序表存储结构及实现

    顺序表存储结构及实现--学生信息管理 一.实验目的 (1) 掌握顺序表的概念及实现方式. (2) 掌握顺序表的存储结构及主要运算:建立.查找.插入.删除等. 二.实验环境 Windows 10,Mic ...

最新文章

  1. MySQL基础篇:事务管理
  2. WCF RIA 服务 (三十二)-- 身份验证、角色、个性化 3
  3. 看到数学就打怵不是你的错:百万人调查发现上黑板做题、作业太多、家长陪写都会引发焦虑|PNAS...
  4. 硬盘重新分区后有一个分区表信息丢失的数据恢复
  5. JAVA程序设计----关于字符串的一些基本问题处理
  6. 分享几个vscode的插件
  7. java迭代器 异常_java迭代器失效 | 学步园
  8. html启动word程序,Word工具栏直接启动外部程序
  9. GARFIELD@09-11-2004
  10. JAX-RPC 与 JAX-WS 的比较
  11. 转AndroidThings技术资料
  12. 正式开始撰写《产品大师》,经验来自点滴的积累
  13. 浅析TVS管的响应时间与TVS管伏安特性曲线
  14. SDN控制器与交换机如何建立连接
  15. 全国计算机等级考试 和ccf,【我与CCF】我与CCF的不解之缘
  16. vue子组件修改props传进来的值、回调函数
  17. 特征锦囊:如何根据变量相关性画出热力图?
  18. DoraCloud for Proxmox桌面云上启用NVIDIA Tesla P4的vGPU功能
  19. AAPT: error: reso 1. mavenCentral():2. jcenter():3. mavenLocal():
  20. 学习ARM开发01-09

热门文章

  1. Docker安装mysql8.0并配置忽略大小写
  2. 创建响应式HTML电子邮件
  3. java GUI mysql实现的薪资工资管理系统项目源码附带视频指导教程
  4. mixly红外遥控问题在线等
  5. 检查凭证录入模板的核算项目研发项目是否录入
  6. 关于最新版mumu模拟器(2.2.16)安装xposed框架
  7. Python在大数据处理中的实践运用,实践操作精选
  8. LESS与SASS的伯与仲
  9. 推荐了这些好书,你看过几本啦?
  10. macbook视频格式转换_为了找到MacBook这个视频转换软件我哭了!太强大了!