用三元組連結串列表示的稀疏矩陣類

小許發表於2012-08-20

稀疏矩陣類: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.實驗結果:

相關文章