用十字链表表示的稀疏矩阵类

总结:

(一)在用十字链表结构表示稀疏矩阵时,矩阵中的每一个非零元素对应一个结点,每个结点五个域:行域,列域,值域,向下域和向右域,行域和列域分别存放非零元素所在的行号和列号,值域存放非零元素的值,向下域指示同一列中下一个非零元素的存储结点序号,向右域指示同一行中下一个非零元素的存储结点序号。

(二)十字链表表示稀疏矩阵的结构特点如下:

(1)稀疏矩阵每一行每一列均用带表头结点的循环链表表示;

(2)表头结点中的行域和列域的值均置为-1(即row=-1,col=-1);

(3)行、列链表的表头结点合用,且这些表头结点存放在一个顺序存储空间中。

因此,只要给出行列链表的头指针,就可以很方便地扫描到稀疏矩阵中的任意一行或一列中的非零元素。

1.十字链表表示的稀疏矩阵类:

#include <iostream>
#include <iomanip>
using namespace std;
template <class T>
struct CN
{
	int i;                    /*非零元素行号*/
	int j;                  /*  非零元素列号*/
	T v;                     /* 非零元素值*/
	CN<T> *down;               /*向下指针*/
	CN<T> *right;              /*向右指针*/
};
template<class T>
class CN_Array
{
	private:                            // 数据成员
		int mm;                          // 稀疏矩阵行数
		int nn;                          // 列数
		int tt;                         //  非零元素个数
		CN<T> * H;                       // 十字链表行列表头结点存储空间
	public:
		CN_Array(){H=NULL;return;}       //   初始化
		void in_CN_Array();              // 以三元组形式从键盘输入稀疏矩阵非零元素
		void th_CN_Array(int,int,T[]);              // 由一般稀疏矩阵转换
		void prt_CN_Array();             // 按行输出稀疏矩阵
};
template <class T>
void CN_Array<T>::in_CN_Array()
{
	int k,m,n;
	T d;
	CN<T> *p,*q;
	cout<<"输入行数 列数 非零元素个数:"<<endl;
	cin>>mm>>nn>>tt;
	if(mm>=nn)m=mm;
	else m=nn;
	H=new CN<T>[m];                     // 申请十字链表行列表头结点存储空间
	for(k=0;k<m;k++)
	{
		H[k].i=-1;H[k].j=-1;H[k].down=&H[k];H[k].right=&H[k];
	}
	cout<<"输入行号 列号 非零元素"<<endl;
	for(k=0;k<tt;k++)
	{
		cin>>m>>n>>d;
		p=new CN<T>;
		p->i=m-1;p->j=n-1;p->v=d;
		q=&H[m-1];
		while(q->right!=&H[m-1]) q=q->right;   // 链接到行尾
		q->right=p;p->right=&H[m-1];
		q=&H[n-1];
		while(q->down!=&H[n-1]) q=q->down;      // 链接到列尾
		q->down=p;p->down=&H[n-1];
	}
	return;
}
//由一般稀疏矩阵转换
template <class T>
void CN_Array<T>::th_CN_Array(int m,int n,T a[])
{
	int p,q;
	CN<T> *s,*k;
	T d;
	mm=m;nn=n;tt=0;
	if(mm>nn)q=mm;
	else q=nn;
	H=new CN<T>[q];
	for(p=0;p<q;p++)
	{
		H[p].i=-1;H[p].j=-1;H[p].down=&H[p];H[p].right=&H[p];
	}
	for(p=0;p<m;p++)
		for(q=0;q<n;q++)
		{
			d=a[p*n+q];
			if(d!=0)
			{
				s=new CN<T>;
				s->i=p;s->j=q;s->v=d;
				k=&H[p];
				while(k->right!=&H[p]) k=k->right;   // 链接到行尾
				k->right=s;s->right=&H[p];
				k=&H[q];
				while(k->down!=&H[q]) k=k->down;      // 链接到列尾
				k->down=s;s->down=&H[q];
				tt=tt+1;
			}
		}
		return;
}
template <class T>
void CN_Array<T>::prt_CN_Array()
{
	int k,kk;
	CN<T> *p;
	for(k=0;k<mm;k++)
	{
		p=&H[k];p=p->right;
		for(kk=0;kk<nn;kk++)        //输出一行     
			if(p->j==kk)
			{
				cout<<setw(8)<<p->v;
				p=p->right;
			}
			else
				cout<<setw(8)<<0;
			cout<<endl;
	}
	return;
}

2.应用实例

#include "CN.Array.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}};
		CN_Array<double> x,y;
		x.th_CN_Array(7,8,&a[0][0]);
		cout<<"输出稀疏矩阵x:"<<endl;
		x.prt_CN_Array();
		y.in_CN_Array();
		cout<<"输出稀疏矩阵y:"<<endl;
		y.prt_CN_Array();
		return 0;
}


 

3.实验结果


 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值