数据结构稀疏矩阵实验报告与代码Word文件下载.docx
《数据结构稀疏矩阵实验报告与代码Word文件下载.docx》由会员分享,可在线阅读,更多相关《数据结构稀疏矩阵实验报告与代码Word文件下载.docx(21页珍藏版)》请在冰豆网上搜索。
Q)
稀疏数组M、N已经存在
求矩阵的和Q=M+N
StatusSubSMatrix(TSMatrixM,TSMatrixN,TSMatrix&
求矩阵的差Q=M-N
StatusTransposeSMatrix(TSMatrixM,TSMatrix&
T)
求矩阵M的转置T
StatusMultSMatrix(TSMatrixM,TSMatrixN,TSMatrix&
求矩阵的积Q=M*N
}ADTList
2.本程序有二个模块:
(1)主程序模块
main()
{
初始化;
接受命令;
显示结果;
}
(2)三元组表单元模块:
实现矩阵抽象数据类型。
三.程序设计
根据算法设计中给出的有关数据和算法,选定物理结构,详细设计需求分析中所要求的程序。
包括:
人机界面设计、主要功能的函数设计、函数之间调用关系描述等。
1、程序基本结构:
2、稀疏矩阵的三元组顺序表存储表示:
typedefstruct{//定义三元组的元素
inti,j;
inte;
}Triple;
typedefstruct{//定义普通三元组对象
Tripledata[MAXSIZE+1];
intmu,nu,tu;
}TSMatrix;
typedefstruct{//定义带链接信息的三元组对象
Tripledata[MAXSIZE+2];
intrpos[MAXROW+1];
}RLSMatrix;
3、基本函数:
1)输入矩阵,按三元组格式输入
boolInPutTSMatrix(P&
T,inty){
cout<
<
"
输入矩阵的行,列和非零元素个数:
"
<
endl;
cin>
>
T.mu>
T.nu>
T.tu;
请输出非零元素的位置和值:
intk=1;
for(;
k<
=T.tu;
k++)
T.data[k].i>
T.data[k].j>
T.data[k].e;
returntrue;
}
2)输出矩阵,按标准格式输出
boolOutPutSMatrix(PT){
intm,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);
T.data[k++].e;
}else{
0"
;
}
3)求矩阵的转置矩阵
boolTransposeSMatrix(){
TSMatrixM,T;
//定义预转置的矩阵
InPutTSMatrix(M,0);
//输入矩阵
intnum[MAXROW+1];
intcpot[MAXROW+1];
//构建辅助数组
intq,p,t;
T.tu=M.tu;
T.mu=M.nu;
T.nu=M.mu;
if(T.tu){
for(intcol=1;
col<
=M.nu;
col++)num[col]=0;
for(t=1;
t<
=M.tu;
t++)++num[M.data[t].j];
cpot[1]=1;
for(inti=2;
i<
i++)cpot[i]=cpot[i-1]+num[i-1];
for(p=1;
p<
p++){
intcol=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];
输入矩阵的转置矩阵为"
OutPutSMatrix(T);
4)两个矩阵相乘
boolMultSMatrix(){
RLSMatrixM,N,Q;
//构建三个带“链接信息”的三元组表示的数组
InPutTSMatrix(M,1);
//用普通三元组形式输入数组
InPutTSMatrix(N,1);
Count(M);
Count(N);
if(M.nu!
=N.mu)returnfalse;
Q.mu=M.mu;
Q.nu=N.nu;
Q.tu=0;
//Q初始化
intctemp[MAXROW+1];
//辅助数组
intarow,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(intx=1;
x<
=N.nu;
x++)
ctemp[x]=0;
Q.rpos[arow]=Q.tu+1;
//当前行的首个非零元素在三元组中的位置为此行前所有非零元素+1
if(arow<
M.mu)tp=M.rpos[arow+1];
elsetp=M.tu+1;
for(p=M.rpos[arow];
tp;
p++){//对当前行每个非零元素进行操作
brow=M.data[p].j;
//在N中找到i值也操作元素的j值相等的行
if(brow<
N.mu)t=N.rpos[brow+1];
elset=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)returnfalse;
Q.data[Q.tu].e=ctemp[ccol];
Q.data[Q.tu].i=arow;
Q.data[Q.tu].j=ccol;
OutPutSMatrix(Q);
5)矩阵的加法
boolAddSMatrix(){
CrossListM,N;
//创建两个十字链表对象,并初始化
CreateSMatrix_OL(M);
CreateSMatrix_OL(N);
输入的两矩阵的和矩阵为:
OLinkpa,pb,pre,hl[MAXROW+1];
//定义辅助指针,pa,pb分别为M,N当前比较的元素,pre为pa的前驱元素
x++)hl[x]=M.chead[x];
for(intk=1;
k++){//对M的每一行进行操作
pa=M.rhead[k];
pb=N.rhead[k];
pre=NULL;
while(pb){//把N中此行的每个元素取出,
OLinkp;
if(!
(p=(OLink)malloc(sizeof(OLNode))))exit(0);
//开辟新节点,存储N中取出的元素
p->
e=pb->
e;
i=pb->
i;
j=pb->
j;
if(NULL==pa||pa->
j>
pb->
j){//当M此行已经检查完或者pb因该放在pa前面
if(NULL==pre)
M.rhead[p->
i]=p;
else
pre->
right=p;
right=pa;
pre=p;
if(NULL==M.chead[p->
j]){//进行列插入
M.chead[p->
j]=p;
down=NULL;
down=hl[p->
j]->
down;
hl[p->
down=p;
pb=pb->
right;
}else
if((NULL!
=pa)&
pa->
j<
j){//如果此时的pb元素因该放在pa后面,则取以后的pa再来比较
pre=pa;
pa=pa->
if(pa->
j==pb->
j){//如果pa,pb位于同一个位置上,则将值相加
e+=pb->
pa->
e){//如果相加后的和为0,则删除此节点,同时改变此元素坐在行,列的前驱元素的相应值
if(NULL==pre)//修改行前驱元素值
M.rhead[pa->
i]=pa->
right=pa->
p=pa;
if(M.chead[p->
j]==p)M.chead[p->
j]=hl[p->
j]=p->
//修改列前驱元素值
down=p->
free(p);
OutPutSMatrix_OL(M);
4、各模块间的关系:
四.测试与分析
1、测试结果
输入1选择矩阵倒置:
输入2选择矩阵的加法:
输入3选择矩阵的乘法:
2、分析与遇到的问题
1)创建稀疏矩阵时,不懂如何用三元组表示元素的输出;
2)需要注意矩阵运算中的特殊状况,
比如:
稀疏矩阵相加时,忘记对应元素相加为0时,在稀疏矩阵中不表示;
矩阵相乘时,必须符合第一个矩阵的列数等于第二个矩阵的行数;
矩阵相加时,第一个矩阵的行列数要和第二个矩阵的行列数相等;
附录:
源代码
#include<
iostream>
iomanip>
usingnamespacestd;
constintMAXSIZE=100;
//定义非零元素的对多个数
constintMAXROW=10;
//定义数组的行数的最大值
typedefstruct{
//定义三元组的元素
//定义普通三元组对象
//定义带链接信息的三元组对象
typedefstructOLNode{//定义十字链表元素
structOLNode*right,*down;
//该非零元所在行表和列表的后继元素
}OLNode,*OLink;
//定义十字链表元素
typedefstruct{//定义十字链表对象结构体
OLink*rhead,*chead;
//系数矩阵的行数,列数,和非零元素个数
}CrossList;
//定义十字链表对象结构体
template<
classP>
T,inty){//输入矩阵,按三元组格式输入
}//输出矩阵,按标准格式输出
//构建辅助数组
//求出每一列中非零元素在三元组中出现的位置
}//求矩阵的转置矩阵
boolCount(RLSMatrix&
T){
=T.mu;
col++)++num[T.data[col].i];
T.rpos[1]=1;
i++)T.rpos[i]=T.rpos[i-1]+num[i-1];
//求取每一行中非零元素在三元组中出现的位置
//用普通三元组形式输入数组
输入的两矩阵的乘矩阵为:
//Q初始化
//辅助数组
x++)//当前行各元素累加器清零
}//两个矩阵相乘
boolCreateSMatrix_OL(CrossList&
M){
intx,y,m;
请输入矩阵的行,列,及非零元素个数"
M.mu>
M.nu>
M.tu;
(M.rhead=(OLink*)malloc((M.mu+1)*sizeof(OLink))))exit(0);
(M.chead=(OLink*)malloc((M.nu+1)*sizeof(OLink))))exit(0);
for(x=0;
x++)
M.rhead[x]=NULL;
//初始化各行,列头指针,分别为NULL
M.chead[x]=NULL;
请按三元组的格式输入数组:
for(inti=1;
i++){
x>
y>
m;
//按任意顺序输入非零元,(普通三元组形式输入)
OLinkp,q;
//开辟新节点,用来存储输入的新元素
i=x;
j=y;
e=m;
if(M.rhead[x]==NULL||M.rhead[x]->
y){
right=M.rhead[x];
M.rhead[x]=p;
for(q=M.rhead[x];
(q->
right)&
right->
y);
q=q->
right);
//查找节点在行表中的插入位置
right=q->
q->
//完成行插入
if(M.chead[y]==NULL||M.chead[y]->
i>
x){
down=M.chead[y];
M.chead[