最新数据结构实验五矩阵的压缩存储与运算.docx

上传人:b****1 文档编号:2309741 上传时间:2022-10-28 格式:DOCX 页数:13 大小:20.46KB
下载 相关 举报
最新数据结构实验五矩阵的压缩存储与运算.docx_第1页
第1页 / 共13页
最新数据结构实验五矩阵的压缩存储与运算.docx_第2页
第2页 / 共13页
最新数据结构实验五矩阵的压缩存储与运算.docx_第3页
第3页 / 共13页
最新数据结构实验五矩阵的压缩存储与运算.docx_第4页
第4页 / 共13页
最新数据结构实验五矩阵的压缩存储与运算.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

最新数据结构实验五矩阵的压缩存储与运算.docx

《最新数据结构实验五矩阵的压缩存储与运算.docx》由会员分享,可在线阅读,更多相关《最新数据结构实验五矩阵的压缩存储与运算.docx(13页珍藏版)》请在冰豆网上搜索。

最新数据结构实验五矩阵的压缩存储与运算.docx

最新数据结构实验五矩阵的压缩存储与运算

 

数据结构实验五矩阵的压缩存储与运算

第五章 矩阵的压缩存储与运算

【实验目的】

1.熟练掌握稀疏矩阵的两种存储结构(三元组表和十字链表)的实现;

2.掌握稀疏矩阵的加法、转置、乘法等基本运算;

3.加深对线性表的顺序存储和链式结构的理解。

第一节 知识准备

    矩阵是由两个关系(行关系和列关系)组成的二维数组,因此对每一个关系上都可以用线性表进行处理;考虑到两个关系的先后,在存储上就有按行优先和按列优先两种存储方式,所谓按行优先,是指将矩阵的每一行看成一个元素进行存储;所谓按列优先,是指将矩阵的每一列看成一个元素进行存储;这是矩阵在计算机中用一个连续存储区域存放的一般情形,对特殊矩阵还有特殊的存储方式。

一、特殊矩阵的压缩存储

1.对称矩阵和上、下三角阵

若n阶矩阵A中的元素满足   =  (0≤i,j≤n-1 )则称为n阶对称矩阵。

对n阶对称矩阵,我们只需要存储下三角元素就可以了。

事实上对上三角矩阵(下三角部分为零)和下三角矩阵(上三角部分为零),都可以用一维数组ma[0.. ]来存储A的下三角元素(对上三角矩阵做转置存储),称ma为矩阵A的压缩存储结构,现在我们来分析以下,A和ma之间的元素对应放置关系。

问题已经转化为:

已知二维矩阵A[i,j],如图5-1,

我们将A用一个一维数组ma[k]来存储,它们之间存在着如图5-2所示的一一对应关系。

 

任意一组下标(i,j)都可在ma中的位置k中找到元素m[k]= ;这里:

k=i(i+1)/2+j   (i≥j)

 图5-1 下三角矩阵

a00a10a11a20…an-1,0…an-1,n-1

k=  0        1      2        3     …     n(n-1)/2  …   n(n+1)/2-1

                    

图5-2下三角矩阵的压缩存储

反之,对所有的k=0,1,2,…,n(n+1)/2-1,都能确定ma[k]中的元素在矩阵A中的位置(i,j)。

这里,i=d-1,(d是使sum=  > k的最小整数),j=  。

2.三对角矩阵

在三对角矩阵中,所有的非零元素集中在以主对角线为中心的带内状区域中,除了主对角线上和直接在对角线上、下方对角线上的元素之外,所有其它的元素皆为零,见图5-3。

 

图5-3 三对角矩阵A

与下三角矩阵的存储一样,我们也可以用一个一维数组ma[0..3n-2]来存放三对角矩阵A,其对应关系见图5-4。

a00a01a10a11a12…an-1,n-2an-1,n-1

k=  0        1      2        3      4       …      3n-3    3n-2

                    

图5-4下三角矩阵的压缩存储

A中的一对下标(i,j)与ma中的下标k之间有如下的关系:

 

公式中采用了C语言的符号,int()表示取整,‘%’表示求余。

二、稀疏矩阵

在m×n 的矩阵中,有t个非零元。

令δ= ,称δ矩阵的稀疏因子,常认为δ≤0.05时称为稀疏矩阵。

稀疏矩阵在工程中有着大量的应用,不少工程问题都可以转化为对稀疏矩阵的计算问题。

如何进行稀疏矩阵的压缩存储呢?

为节省存储空间,应只存储非零元素。

除了存储非零元的值之外,还必须记下所在行和列的位置(i,j),即一个三元组(i,j,  )唯一确定了矩阵A的一个非零元素。

1.三元组顺序表

以顺序存储结构来表示三元组表,则可称稀疏矩阵的一种压缩存储方式。

//稀疏矩阵的三元组顺序表存储表示。

#define MaxSize 10  //用户自定义

typedef int Datatype; //用户自定义

typedef struct{  //定义三元组

 int i;//非零元的行下标

int j; //非零元的列下标

  Datatype v; //非零元的数据值

}TriTupleNode;

typedef struct{

TriTupleNode data[MaxSize];//非零元的三元组表

int m,n,t;//矩阵行,列及三元组表长度

}TriTupleTable;

2.十字链表

当矩阵的非零元个数和位置在操作过程中变化较大时,就不宜采用顺序存储结构来表示三元组的线性表,采用纵横交叉的十字链表就比较好。

在十字链表中,每个非零元可用一个含五个域的结点表示,其中i, j和e三个域分别表示该非零元所在的行、列和非零元的值,向右域right用以链接同一行中下一个非零元。

向下域down用以链接同一列中下一个非零元。

同一行中的非零元通过right域链接成一个线性链表,每个非零元既是某个行链表中的一个结点,又是某个列链表中的一个结点,整个矩阵构成了一个十字交叉的链表,故称这样的存储结构为十字链表,如图5-5所示。

 

图5-5 稀疏矩阵M的十字链表

typedef int Datatype; //用户自定义

typedef struct OLNode{

  int i,j;                  //该非零元的行和列下标

Datatype v;      

Struct OLNode *right,*down //该非零元所在行表和列表的后继链域

}OLNode;*OLink;

typedef struct {               

OLink *rhead,*chead

int mu,nu,tu;

}CrossList;

第二节用三元组表实现稀疏矩阵的基本操作

【问题描述】用三元组表实现稀疏矩阵的按列转置。

【数据描述】

typedef int Datatype; //用户自定义

typedef struct

{//定义三元组

int i,j;  // 非零元素的行下标和列下标

Datatype v;

}TriTupleNode;

typedef struct{//定义三元组表

TriTupleNode data[MaxSize];

int m,n,t;//矩阵行,列及三元组表长度

}TriTupleTable;

【算法描述】

按照列序来进行转置。

为了找到每一列中所有的非零元素,需要对其三元组表从第一行起整个扫描一遍。

Status TransposeSMatrix(TriTupleTable a, TriTupleTable &b){

b.m=a.n;b.n=a.m;b.t=a.t;

if(b.t){

q=0;

for(col=1;col<=a.n;++col)

      for(p=0;p<=a..t;++p)

      if(a.data[p].j==col){

b.data[q].i=a.data[p].j;b.data[q].j=a.data[p].i;

b.data[q].v=a.data[p].v;++q;}

}

return OK;

}

【C源程序】

#include 

#include 

#define Ok 1

#define Maxsize 10 //用户自定义三元组最大长度

typedef struct{     /*定义三元组表*/

int i,j;

int v;

}TriTupleNode;

typedef struct{  /*定义三元组表*/

 TriTupleNode data[Maxsize];

 int m;

 int n;

 int t; /*矩阵行,列及三元组表长度*/

 }TriTupleTable;

 void InitTriTupleNode (TriTupleTable *a){  /*输入三元组表*/

 int i,j,k,val,maxrow,maxcol;

 char contiue;

 maxrow=0;

 maxcol=0;

 i=j=0;

 k=0;

 while(i!

=-1&&j!

=-1){   /*rol=-1&&col=-1结束输入*/

 printf("input row \n");

 scanf("%d",&i);

 printf("input col \n");

 scanf("%d",&j);

 printf("input value\n");

 scanf("%d",&val);

 a->data[k].i=i;

 a->data[k].j=j;

 a->data[k].v=val;

 if (maxrow

 if (maxcol

 k++;

}

 a->m=maxrow;a->n=maxcol;a->t=k-1;

 }

 void showMatrix(TriTupleTable *a){   /*输出稀疏矩阵*/

int p,q;

  int t=0;

 for(p=1;p<=a->m;p++)

 {for(q=1;q<=a->n;q++)

  { if (a->data[t].i==p&&a->data[t].j==q)

    {printf("%d   ",a->data[t].v);

    t++;

    }

    else printf("0   ");

    }

   printf("\n"  );

   }

  }

  TransposeSMatrix(TriTupleTable *a,TriTupleTable *b)

  {int q,col,p;

  b->m=a->n;b->n=a->m;b->t=a->t;

  if(b->t)

  {q=0;

  for(col=1;col<=a->n;++col)

for(p=0;pt;++p)

 if(a->data[p].j==col)

 { b->data[q].i=a->data[p].j;

  b->data[q].j=a->data[p].i;

  b->data[q].v=a->data[p].v;++q;

  }

 }

}

   void main( void)

   {TriTupleTable *a,*b;

   InitTriTupleNode(a);

   showMatrix(a);  /*转置前*/

   TransposeSMatrix(a,b);

   showMatrix(b);  /*转置后*/

   }

【测试数据】

  输入:

                          输出:

1 2 0 0                       1 4 0

4 3 0 7                       2 3 0

0 0 0 8                       0 0 0

                              0 7 8

【说明】

分析算法,主要的工作是在p和col的两重循环中完成,算法的时间复杂度为O(n*t)。

如果非零元素个数t和m*n同数量级时,算法的时间复杂度变为O(m*n2)。

【实验题】

1.稀疏矩阵按行序进行转置。

2.两个稀疏矩阵的相加运算。

第三节 十字链表表示稀疏矩阵的基本操作

【问题描述】两个相同行数和列数的稀疏矩阵用十字链表实现加法运算

【数据描述】

typedef struct ele {/* 十字链表结点类型*/

  int row, col;

  double val;

  struct ele *rig

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1