稀疏矩阵类:XL_array.h
#include <iostream>
#include <iomanip>
using namespace std;
template <class T>
struct B
{
int i; /*非零元素行号*/
int j; /*非零元素列号*/
T v; /*非零元素值*/
B<T> *next; /* 指向下一个结点的指针*/
};
template <class T>
class XL_array
{
private:
int mm; /* 稀疏矩阵的行数*/
int nn; /* 稀疏矩阵的列数*/
int tt; /* 稀疏矩阵非零个数*/
B<T> * head; /*三元组链表头指针*/
public:
XL_array()
{
head=NULL;return; /* 三元组链表初始化*/
}
void in_XL_array(); /*以三元组形式从键盘输入稀疏矩阵非零元素*/
void th_XL_array(int,int,T[]); /*由一般稀疏矩阵转换*/
void prt_XL_array(); /*按行输出稀疏矩阵*/
XL_array tran_XL_array(); /*稀疏矩阵转置*/
XL_array operator +(XL_array &); /*稀疏矩阵相加*/
};
//以三元组形式从键盘输入稀疏矩阵非零元素
template<class T>
void XL_array<T>::in_XL_array()
{
int k,m,n;
T d;
B<T> *p,*q;
cout<<"请输入行数 列数 非零元素个数:"<<endl;
cin>>mm>>nn>>tt;
q=NULL;
cout<<"输入行号 列号 非零元素值:"<<endl;
for(k=0;k<tt;k++)
{
cin>>m>>n>>d;
p=new B<T>;
p->i=m-1;
p->j=n-1;
p->v=d;
p->next=NULL;
if(head==NULL)head=p;
else q->next=p;
q=p;
}
return;
}
/*由一般稀疏矩阵转换*/
template<class T>
void XL_array<T>::th_XL_array(int m,int n,T a[])
{
int t=0,p,q;
B<T>*s,*k;
T d;
mm=m;nn=n;
k=NULL;
for(p=0;p<m;p++)
for(q=0;q<n;q++)
{
d=a[p*n+q];
if(d!=0)
{
s=new B<T>;
s->i=p;
s->j=q;
s->v=d;
s->next=NULL;
if(NULL==head) head=s;
else k->next=s;
k=s;
t=t+1;
}
}
tt=t;
return;
}
/*按行输出稀疏矩阵*/
template<class T>
void XL_array<T>::prt_XL_array()
{
int k,kk;
B<T> *p;
p=head;
for(k=0;k<mm;k++) /*按行输出*/
{
for(kk=0;kk<nn;kk++) /*输出一行*/
if (p!=NULL)
{
if((p->i==k)&&(p->j==kk)) /*输出非零元素*/
{
cout<<setw(8)<<p->v;
p=p->next;
}
else
cout<<setw(8)<<0;
}
else
cout<<setw(8)<<0;
cout<<endl;
}
return;
}
/*稀疏矩阵转置*/
template <class T>
XL_array<T> XL_array<T>::tran_XL_array()
{
XL_array<T> at; /*定义转置矩阵对象*/
int p;
B<T> *s,*k,*q;
at.mm=nn;at.nn=mm;at.tt=tt; /*转置矩阵行列数及非零元素个数*/
k=NULL;
for(p=0;p<nn;p++)
for(q=head;q!=NULL;q=q->next)
{
if(q->j==p)
{
s=new B<T>;
s->i=q->j;
s->j=q->i;
s->v=q->v;
s->next=NULL;
if(k==NULL)at.head=s;
else k->next=s;
k=s;
}
}
return at;
}
//稀疏矩阵相加
template <class T>
XL_array<T> XL_array<T>::operator+(XL_array &b)
{
XL_array<T> c;
T d;
B<T> *m,*n,*q,*s;
int k=0;
q=NULL; /*记住链尾 */
if((mm!=b.mm)||(nn!=b.nn))
cout<<"不能相加"<<endl;
else
{
m=head;n=b.head;
while((m!=NULL)&&(n!=NULL))
{
if(m->i==n->i) /* 行号相同*/
{ if(m->j==n->j) /* 列号相同则相加*/
{
d=m->v+n->v;
if(d!=0) /* 相加后非零*/
{
s=new B<T>; /*申请一个三元组结点*/
s->i=m->i;
s->j=m->j;
s->v=d;
s->next=NULL;
if(q==NULL)c.head=s;
else q->next=s;
q=s; /*记住链尾*/
k=k+1; /*非零元素个数加1*/
}
m=m->next;n=n->next;
}
else if (m->j<n->j) /*列号不同则复制列号小的一项*/
{
s=new B<T>;
s->i=m->i;s->j=m->j;s->v=m->v;
s->next=NULL;
if(q==NULL)c.head=s;
else q->next=s;
q=s;
k=k+1;
m=m->next;
}
else /* 列号不同复制另一项*/
{
s=new B<T>;
s->i=n->i;s->j=n->j;s->v=n->v;
s->next=NULL;
if(q==NULL)c.head=s;
else q->next=s;
q=s;
k=k+1;
n=n->next;
}
}
else if(m->i<n->i) /*复制矩阵中行号小的非零元素*/
{
s=new B<T>;
s->i=m->i;s->j=m->j;s->v=m->v;
s->next=NULL;
if(q==NULL)c.head=s;
else q->next=s;
q=s;
k=k+1;
m=m->next;
}
else /* 复制另一矩阵中本行的一个非零元素*/
{
s=new B<T>;
s->i=n->i;s->j=n->j;s->v=n->v;
s->next=NULL;
if(q==NULL)c.head=s;
else q->next=s;
q=s;
k=k+1;
n=n->next;
}
}
while(m!=NULL) /*复制矩阵中剩余的非零元素*/
{
s=new B<T>;
s->i=m->i;s->j=m->j;s->v=m->v;
s->next=NULL;
if(q==NULL)c.head=s;
else q->next=s;
q=s;
k=k+1;
m=m->next;
}
while(n!=NULL) /*复制另一个矩阵中剩余的非零元素个数*/
{
s=new B<T>;
s->i=n->i;s->j=n->j;s->v=n->v;
s->next=NULL;
if(q==NULL)c.head=s;
else q->next=s;
q=s;
k=k+1;
n=n->next;
}
c.mm=mm;c.nn=nn;c.tt=k;
}
return c; /* 返回想加结果*/
}
2.应用实例
#include "XL_array.h"
#include <stdlib.h>
int main()
{
double a[7][8]={{0,0,3,0,0,0,0,1},
{0,0,0,0,0,0,0,0},
{9,0,0,0,0,0,0,0},
{0,0,0,0,7,0,0,0},
{0,0,0,0,0,0,6,0},
{0,0,0,2,0,3,0,0},
{0,0,5,0,0,0,0,0}};
XL_array<double> x,y,z,xt,c;
x.th_XL_array(7,8,&a[0][0]);
cout<<"输出稀疏矩阵x:"<<endl;
x.prt_XL_array();
xt=x.tran_XL_array();
cout<<"输出转置稀疏矩阵xt:"<<endl;
xt.prt_XL_array();
y.in_XL_array();
cout<<"输出稀疏矩阵y:"<<endl;
y.prt_XL_array();
z=x+y;
cout<<"输出稀疏矩阵z=x+y:"<<endl;
z.prt_XL_array();
system("pause");
return 0;
}
3.实验结果: