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