实验5数组Word文件下载.docx
《实验5数组Word文件下载.docx》由会员分享,可在线阅读,更多相关《实验5数组Word文件下载.docx(12页珍藏版)》请在冰豆网上搜索。
}TSMatrix;
五、实验环境
PC微机
DOS操作系统或Windows操作系统
TurboC程序集成环境或VisualC++程序集成环境
六、实验代码
#include<
iostream>
usingnamespacestd;
#include<
malloc.h>
#defineERROR-1
#defineOK1
typedefintStatus;
intCreatSMatrix(TSMatrix&
M)
{//创建稀疏矩阵
inti;
cout<
<
"
请输入稀疏矩阵的行数、列数和非零元的个数(以空格隔开):
;
cin>
>
M.mu>
M.nu>
M.tu;
while(M.tu>
M.mu*M.nu||M.mu<
1||M.nu<
1||M.tu<
1){
非法输入!
\n"
;
}
if(M.tu>
MAXSIZE)returnERROR;
for(i=1;
i<
=M.tu;
i++)
{
请依次输入第"
个非零元所在行、列以及值:
M.data[i].i>
M.data[i].j>
M.data[i].e;
while(M.data[i].i>
M.mu||M.data[i].i<
1||M.data[i].j>
M.nu
||M.data[i].j<
1||M.data[i].e==0){
cout<
输入不合法,请重新输入!
}
}
return0;
intFastTransposeSMatrix(TSMatrixM,TSMatrix&
T){
//采用三元组顺序表存储结构表示,求稀疏矩阵M的转置矩阵T。
T.mu=M.nu;
T.nu=M.mu;
T.tu=M.tu;
intcol,t,p,q;
int*num=(int*)malloc(M.nu*sizeof(int));
int*cpot=(int*)malloc(M.nu*sizeof(int));
if(T.tu){
for(col=1;
col<
=M.nu;
++col)num[col]=0;
for(t=1;
t<
++t)++num[M.data[t].j];
//求M中每一列含非零元个数
cpot[1]=1;
//求第col列中第一个非零元在b.data中的序号
for(col=2;
++col)cpot[col]=cpot[col-1]+num[col-1];
for(p=1;
p<
++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];
}//for
}//if
returnOK;
}//FastTransposeSMatrix
intAddMatrix(TSMatrixa,TSMatrixb,TSMatrix&
c){
//将矩阵a和矩阵b相加得到矩阵c
inti=1,j=1,k=1;
intv;
if(a.mu!
=b.mu||a.nu!
=b.nu)//如果行列不相等
return0;
if(a.tu==0&
&
b.tu==0)return0;
c.mu=a.mu;
c.nu=a.nu;
//c的行列数与a的相同
while(i<
=a.tu&
j<
=b.tu)//处理a和b中的每个元素
{
if(a.data[i].i==b.data[j].i)//行号相等时
if(a.data[i].j<
b.data[j].j)//a元素的列号小于b元素的列号
c.data[k].i=a.data[i].i;
//将a元素添加到c中
c.data[k].j=a.data[i].j;
c.data[k].e=a.data[i].e;
k++;
i++;
elseif(a.data[i].j>
b.data[j].j)//a元素的列号大于b元素的列号
c.data[k].i=b.data[i].i;
c.data[k].j=b.data[i].j;
c.data[k].e=b.data[i].e;
j++;
else//a元素的列号等于b元素的列号
v=a.data[i].e+b.data[j].e;
if(v!
=0)//只将不为0的结果添加到c中
c.data[k].e=v;
elseif(a.data[i].i<
b.data[j].i)//a元素的行号小于b元素的行号
//将a元素添加到c中
else//a元素的行号大于b元素的行号
c.data[k].i=b.data[j].i;
//将b元素添加到c中
c.data[k].j=b.data[j].j;
c.data[k].e=b.data[j].e;
=a.tu)//若a中还有元素
{//将剩下的元素添加到c中
while(j<
=b.tu)//若b中还有元素
c.tu=k-1;
//跳出循环时k多加了一次
两稀疏矩阵相加成功!
}
voidShowSMatrix(TSMatrixM){
//输出矩阵M,只输出含非零元的行、列以及元素值
遍历结果为:
*****************\n"
for(intii=1;
ii<
=M.mu;
ii++){
for(intjj=1;
jj<
jj++){
intcnt=1;
intflag=0;
while(cnt<
=M.tu){
if(M.data[cnt].i==ii&
M.data[cnt].j==jj){
flag=1;
cout<
M.data[cnt].e<
"
}
cnt++;
}
if(flag==0){
cout<
'
0'
endl;
voidmenu()
{
**********************************\n"
*稀疏矩阵基本操作*\n"
*1.转置*\n"
*2.相加*\n"
*3.遍历*\n"
*0.退出*\n"
cout<
请输入要选择的选项(0-3):
intmain(){
TSMatrixA,B,C,D,Q;
创建A矩阵\n"
CreatSMatrix(A);
创建B矩阵\n"
CreatSMatrix(B);
menu();
cin>
i;
while(i){
switch(i){
case1:
charm1;
cout<
请选择要转置的矩阵,输入A或者B:
cin>
m1;
if(m1=='
A'
)D=A;
elseif(m1=='
B'
)D=B;
else{
ERROR!
return0;
FastTransposeSMatrix(D,C);
ShowSMatrix(C);
break;
}
case2:
AddMatrix(A,B,C);
case3:
请选择要遍历的矩阵,输入A或者B:
else{cout<
ShowSMatrix(D);
}
default:
error\n"
break;
//输入i值不合法时退出操作并报错
请选择操作:
七、测试数据及结果
整体操作过程:
八、思考题
1、如何提高矩阵转置算法效率?
在上面的代码中我使用的是简单的矩阵转置算法,实际上书上也将了矩阵的快速转置算法。
快速转置算法通过添加辅助向量num[]和cpot[],对于稀疏矩阵而言将时间复杂度从O(mu*nu)减为O(nu+tu)。
2、如果用十字链表方式表示稀疏矩阵的话,如何来实现矩阵的相加操作呢?
书上讲了十字链表的相加操作。
主要是花费功夫在链表链接域的指向上。
八、心得体会
稀疏矩阵的相加算法参考了书上的两线性表的合并算法2.2的思路,即用while循环对每一个非零元进行操作,判断两个非零元的行数、列数相等时进行加和,不同的话根据行、列的大小比较分别加到新的稀疏矩阵中,最后将剩下的非零元加入到新的稀疏矩阵的后面。
不过这个算法要求两个稀疏矩阵的data[i]里的行、列要按非递减排列,因此初始化时要按非递减的输入,有一定的局限性。
通过这次实验对稀疏矩阵的存储结构以及转置、相加操作有了一定的了解,加深了对稀疏矩阵操作的理解。