下三角矩阵的压缩存储(实验报告)
数据结构实验五矩阵的压缩存储与运算学习资料

数据结构实验五矩阵的压缩存储与运算第五章矩阵的压缩存储与运算【实验目的】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 下三角矩阵a00 a10 a11 a20 … an-1,0 … an-1,n-1k= 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。
规律分布特殊矩阵的压缩存储

【本节要点】
= Loc( A[ 1 ][ 1 ])+( 2 ( i-1 )+ j -1)*size
1、 规律分布特殊矩阵的压缩存储原则:按规律存放非零元素;
2、 按规律找出地址计算公式
思考题:类同按行为主序,请给出按列或按行为主序条件下上三角矩阵以及对称矩阵的 相关推导。 2 .带状矩阵
( 1 )带状矩阵描述:在矩阵中的所有非零元素都集中在以主对角线为中心的带状区域中。 其中最常见的是三对角带状矩阵,如图 3 所示。
a11 A12
a21 A22 a23
A32 a33 a34
( 2 )三对角带状矩阵特点
数组 C
a11 a12 a21 a22 a23 a31 … ann
Loc(i,j)
1 2 3 4 5 6 … 3n-2
图 4 带状矩阵的压缩形式
②确定非零元素在一维数组空间中的地址 Loc ( A[ i][ j])= Loc ( A[ 1 ][ 1 ])+(前 i-1 行非零元素个数+第 i 行中 aij 前非零元素个
数)*size 前 i-1 行元素个数=3 ×( i-1 )- 1 (因为第 1 行只有 2 个非零元素); 第 i 行中 ai j 前非零元素个数=j-i +1 ,其中
j-i=
-1 ( j<i) 0 (j=i) 1 (j>i)
二维数组的压缩存储矩阵

数据结构实验报告学号:2015111898姓名:许明华专业:计算机科学与技术知识范畴:数组与广义表完成日期:2017年04月21日实验题目:基于压缩存储的半三角矩阵乘法运算的实现实验内容及要求:已知两个n阶下半三角矩阵的乘积仍为n阶下半三角矩阵。
编程输入两个n阶下半三角矩阵,输出这两个矩阵的乘积。
要求n阶下半三角矩阵采用一维数组压缩存储(即只存储下半三角)。
程序先从键盘(或字符文件)输入n值,建立三个矩阵的一维数组动态存储结构,然后从键盘(或字符文件)输入两个半三角矩阵,最后输出计算结果到屏幕上(或另一个字符文件中)。
例如:键盘输入为:312 34 5 6-1-2 -3-4 -5 -6则输出为:-1-8 -9-38 -45 -36实验目的:掌握半三角矩阵的顺序存储结构。
数据结构设计简要描述:序言:这是本学期第五个实验,本实验是要求我们将两个二维半三角矩阵压缩存储为一维矩阵,并对其进行乘法操作,得到一个一维的压缩存储矩阵,并将其打印输出;数据结构简单设计:本实验主要可分为两个大的模块(压缩存储矩阵、压缩矩阵相乘)。
第一,我们通过键盘键入一个数组的阶数,然后输入两个半三角矩阵,,但是这两个半三角矩阵要进行压缩存储为一维矩阵,关键操作即(m = (i*(i+1))/2 + j),即可将二维下标转化为一维下标;第二,运用公式 i]][[*]][[jjkbkia来进行相乘操作,求得两个下三角矩阵的乘积。
算法设计简要描述:1,通过(m = (i*(i+1))/2 + j)将二维下标转化为一维下标进行输入,得到压缩存储矩阵;2,运用公式 i]][[*]][[jjkbkia进行乘积操作,但是乘数矩阵下标和结果矩阵的下标并没有同步,所以运用三个公式来进行分离操作,m1 = (i*(i+1))/2 + k;m2 = (k*(k+1))/2 + j;m = (i*(i+1))/2 + j;c [m] += a[m1]*b[m2];这样即能实现相乘的操作,但是每一次的c[m]没有进行初始化,所以在每一次得到m值后,进行操作c[m] = 0;输入/输出设计简要描述:输入:1,输入下三角存储矩阵的阶数n;2,输入第一个下三角矩阵,如1 2 3 4 5 6;3,输入第二个下三角矩阵,如-1 -2 -3 -4 -5 -6;输出:1,输入2操作后,按存储矩阵格式输出打印第一个下三角矩阵;2,输入3操作后,按存储矩阵格式输出打印第二个下三角矩阵,并输出打印两个矩阵的乘积矩阵编程语言说明:1,编程软件,CodeBlocks 16.0;2,代码均用C语言实现;3,输入输出采用C语言的printf和scanf函数;4,程序注释采用C/C++规范;主要函数说明:void input_Arr( int, int );//输入半三角矩阵声明void print( int, int );//输出打印半三角矩阵声明int print_Array( int, int, int, int);//两个半三角矩阵的乘法运算声明程序测试简要报告:见截图:源程序代码:#include<stdio.h>//函数声明部分void input_Arr( int, int );//输入半三角矩阵声明void print( int, int );//输出打印半三角矩阵声明int print_Array( int, int, int, int);//两个半三角矩阵的乘法运算声明//输入半三角矩阵void input_Arr(int a[], int n){int m;printf("请输入数组:\n");for(int i = 0 ; i < n ; i ++){for(int j = 0 ; j <= i ; j ++)//这里在存储时我只存储了下三角对应的数组元素,,所以是j<=i,而不是j<n{m = (i*(i + 1))/2 + j;//这一步操作是关键所在,因为要将二维数组压缩存储为一维数组的话,我们来看,//二维数组的下标为i和j,但是一维数组的下标只有一个,怎么办呢,//这时候我们就可以根据公式来将二维数组的下标转化为对应的一维数组的下标,所得到的就是对应位置的对应下标scanf("%d",&a[m]); //输入对应的下三角矩阵}}}//输出打印半三角矩阵void print(int a[], int n){int m = 0;for(int i = 0 ; i < n ; i ++){for(int j = 0 ; j <= i ; j ++){m = (i*(i + 1))/2 + j;//打印操作,同上面printf("%d ",a[m]);}printf("\n");}}//两个半三角矩阵的乘法运算int print_Array(int a[], int b[], int c[], int n){int i = 0, j = 0;int k, m, m1, m2 ;//k为进行乘法操作过程的中间变量,m为乘积过后的一维压缩数组的下标,m1为第一个数组的压缩存储的下标,m2为第二个数组的压缩存储的下标for( i = 0; i < n ; i ++){for( j = 0; j <= i ; j ++)//限定在下三角元素中进行{m = (i*(i + 1))/2 + j;//将二维下标转化为压缩存储的一维下标c[m] = 0; //这一步很重要,我想了很久才想到这一步的,就是每一次将c[m]的初值赋为0,因为后面要执行c[m] +=操作,如果不仅赋初值的话,每次的第一个c[m]就是没有进行初始化,//那它就是一个无穷大的数,得出来的乘积之和就是一个无穷大的数for(k = j ; k <= i ; k ++)//由于是下三角进行相乘,所以所有的上三角元素都为零,不需要再进行乘积操作,{m1 = (i*(i + 1))/2 + k;//第一个压缩存储的数组的一维下标m2 = (k*(k + 1))/2 + j;//第二个压缩存储的数组的一维下标c[m] += a[m1]*b[m2];//进行乘积操作}}}return 0;}int main(){int n ;//数组长度nint a[100],b[100],c[100];//定义三个一维数组printf("请输入数组大小n:\n");scanf("%d",&n);input_Arr(a,n);//调用输入下三角矩阵函数printf("数组一为:\n");print(a,n);//输出下三角矩阵input_Arr(b,n);//同上printf("数组二为:\n");print(b,n);//同上print_Array(a,b,c,n);//调用下三角矩阵相乘函数printf("数组的乘积为:\n");print(c,n);//输出相乘之后的下三角矩阵return 0; }。
第4章专题3矩阵的压缩存储

三元组表=( (0,0,15), (1,1,11), (2,3,6), (4,0,9) ) 如何存储三元组表?
清华大学出版社
数据结构(C++版)第2版
4.3 矩阵的压缩存储
稀疏矩阵的压缩存储——三元组顺序表 采用顺序存储结构存储三元组表
15 0 0 22 0 -15
0 11 3 0 0 0
A=
0 0
0 0 a43 a44 a45 0 0 0 a54 a55
(a) 三对角矩阵
按行 存储
元素aij在一维数组中的序号
=2 + 3(i-2)+( j-i + 2) =2i+ j -2 ∵一维数组下标从0开始
∴元素aij在一维数组中的下标
= 2i+ j -3
(b) 寻址的计算方法
0 1 2 3 4 5 6 7 8 9 10 11 12
0 0
0 0
6 0
0 0
0 0
91 0 0 0 0 0
三元组顺序表是否 需要预留存储空间?
稀疏矩阵的修改操作
三元组顺序表的插入/删除操作
清华大学出版社
数据结构(C++版)第2版
4.3 矩阵的压缩存储
稀疏矩阵的压缩存储——三元组顺序表
采用顺序存储结构存储三元组表
15 0 0 22 0 -15
0 11 3 0 0 0
上三角中的元素aij(i<j),因为aij=aji,则访问和 它对应的元素aji即可,即:k=j×(j+1)/2+i -1 。
清华大学出版社
数据结构(C++版)第2版
4.3 矩阵的压缩存储
特殊矩阵的压缩存储——三角矩阵
三角矩阵在压缩存储下的转置矩阵源代码

#include<stdio.h>#include<stdlib.h>#define max 20#define zero 0typedef struct{int i,j,v;}node;typedef struct{node data[max];int m;}TSmatrix;TSmatrix *Setmatrix(){ //建三对角矩阵TSmatrix *T;T=(TSmatrix*)malloc(sizeof(TSmatrix));printf("请输入矩阵行数或列数:\n");scanf("%d",&T->m);printf("建立三对角矩阵:\n");for(int n=0;n<3*T->m-2;n++)scanf("%d%d%d",&T->data[n].i,&T->dat a[n].j,&T->data[n].v);return T;}TSmatrix *Trabsmatrix(TSmatrix *T){ //三对角矩阵转置int n,k,temp;TSmatrix *F;F=(TSmatrix*)malloc(sizeof(TSmatrix));F->m=T->m;for(n=0;n<3*T->m-2;n++){ //将结点信息存入新三元组表中temp=2*T->data[n].j+T->data[n].i; //计算待存入三元数组下标F->data[temp].i=T->data[n].j;F->data[temp].j=T->data[n].i;F->data[temp].v=T->data[n].v;}return F;}void TSmatrixout(TSmatrix *T){ //三对角矩阵输出int a,b,n;n=0;for(a=0;a<T->m;a++){for(b=0;b<T->m;b++){if(T->data[n].i==a&&T->data[n].j==b){printf("%-5d",T->data[n].v);n++;}elseprintf("%-5d",zero);}printf("\n");}}void main(){TSmatrix *T;T=Setmatrix();printf("三对角矩阵:\n");TSmatrixout(T);T=Trabsmatrix(T);printf("转置后三对角矩阵:\n");TSmatrixout(T);}问题分析:本程序要求实现对压缩存储下的三对角矩阵进行转置,为实现上述功能,需要解决的关键问题是三对角矩阵压缩存储及转置过程。
最新数据结构实验五矩阵的压缩存储与运算

精品资料数据结构实验五矩阵的压缩存储与运算........................................第五章矩阵的压缩存储与运算【实验目的】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 下三角矩阵a00 a10 a11 a20 … an-1,0 … an-1,n-1k= 0 1 23 …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= 。
下三角矩阵的压缩存储

下三角矩阵的压缩存储下三角矩阵的压缩存储是一种有效的数据结构,用于节省内存空间和提高数据访问效率。
下面将介绍下三角矩阵的定义和压缩存储方法。
一、下三角矩阵的定义下三角矩阵是指主对角线以上的元素均为0的矩阵。
例如,一个3阶的下三角矩阵可以表示为:a21 a22 0a31 a32 a33其中,a11、a21、a22、a31、a32和a33为矩阵中的元素。
下三角矩阵的特点是上三角部分全为0,只有下三角部分有非零元素。
由于下三角矩阵的上三角部分全为0,对于大规模矩阵而言,存储这些0元素是一种浪费。
因此,可以使用一维数组来压缩存储下三角矩阵。
具体的压缩存储方法是,将下三角矩阵按行从上到下、从左到右的顺序压缩成一个一维数组。
压缩后的数组长度为矩阵下三角部分的元素个数,即n * (n + 1) / 2,其中n为矩阵的阶数。
例如,对于上述的3阶下三角矩阵,按行压缩后的一维数组为:a11, a21, a22, a31, a32, a33压缩后的一维数组长度为6,分别对应着下三角矩阵中的非零元素。
在压缩存储的时候,需要注意矩阵元素在一维数组中的下标与矩阵中的行列下标之间的对应关系。
一维数组的下标可以通过如下公式计算得到:arrayIndex = i * (i + 1) / 2 + j其中,i和j分别为矩阵元素在矩阵中的行列下标,arrayIndex为该元素在一维数组中的下标。
通过下三角矩阵的压缩存储,可以减少存储空间的占用,并且提高访问矩阵元素的效率。
在实际应用中,下三角矩阵的压缩存储常用于稀疏矩阵的表示和处理。
总结:下三角矩阵的压缩存储是一种有效的数据结构,可以节省内存空间,并提高数据访问效率。
压缩存储的方法是将下三角矩阵按行压缩成一维数组,通过计算数组下标与矩阵元素在矩阵中的下标之间的对应关系,可以实现矩阵元素的访问。
这种压缩存储方式在稀疏矩阵的处理中具有广泛的应用。
矩阵的压缩存储

矩阵的压缩存储前⾔ ⼀⼊编程深似海,从此砖头是爱⼈,⽇⽇搬,夜夜搬,搬到天荒地⽼,精尽⼈亡,直教⼈失去了⾃我,忘记了时间,忽然之间发现九⽉份快没了,赶紧写篇博客打个卡,证明⼀下我还活着。
数组与矩阵 数组是由⼀组相同类型的数据元素构成的有限序列,访问数据元素的⽅式是使⽤元素各⾃的序号进⾏访问,也就是下标。
数组它本⾝是线性表的推⼴,⼀维数组就是⼀个向量形式的线性表,⼆维数组就是由⼀维数组组成的线性表。
在许多科学计算和⼯程应⽤中,经常要⽤到矩阵的概念,我们⽤的最多的其实就是Mysql的表,表数据都是⾏列存储,这就是矩阵。
由于矩阵具有元素数⽬固定以及元素按下标关系有序排列等特点,所以在使⽤⾼级语⾔编程时,⼀般都是⽤⼆维数组来存储矩阵。
数组的顺序存储为什么是顺序存储? 我想问这个问题就太低级了。
因为它是数组,数据的存储⽅式分为顺序存储和链式存储两种,数组⼀旦被定义,他的维数和维界就已固定,除结构的初始化和销毁外,数组只会有存取元素和修改元素的操作,不存在插⼊和删除操作,所以数组适合⽤顺序存储。
数组存放在内存中的映射关系 数组可以是多维的,但是内存空间却是⼀维的,所以我们就要把多维数组通过⼀定的映射顺序把它变成⼀维的,然后存储到内存空间之中。
在⼤多数⾼级编程语⾔中,多维数组在内存中通常有两种不同的顺序存储⽅式,按⾏优先顺序存储和按列优先顺序存储。
举个例⼦,以下3⾏4列的⼀个⼆维数组矩阵:a1,a2,a3,a4b1,b2,b3,b4c1,c2,c3,c4 按⾏优先顺序存储: 按列优先顺序存储:地址计算 地址计算的意思就是给定数组下标,求在⼀维内存空间的地址,从⽽取出数据。
我们先来看⼀维数组的地址计算 ⼀维数组内的元素只有⼀个下标,存储⽅法和普通的线性表⼀样。
如⼀维数组 A = [a1,a2,a3,......ai,.........,an],每个元素占⽤size个存储单元(就是内存⼤⼩),那么元素ai的存储地址为 A[0]的位置 + (i-1)*size再来看⼆维数组的地址计算 以⼆维数组Amn为例,⾸元素为A[0][0],数组中任意元素A[i][j]的地址为:A[0][0]的位置 + (n * (i-1) + (j-1))* size;⽐如:⼀个5⾏4列的⼆维数组A,按⾏存储,其中每个元素占2个存储单元,⾸元素地址是1000,求第3⾏第2列的元素在内存中的地址。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
下三角矩阵的压缩存储(实验报告)
1、实验目的和要求理解和掌握下三角矩阵的压缩存储技术,使用C语言根据相应算法编写一个程序,实现下三角矩阵的压缩存储。
要求仔细阅读下面的内容,编写C程序,上机通过,并观察其结果,写出实验报告书。
二、实验内容和原理内容:用一个一维数组存储一个5X5的下三角矩阵。
原理:对于下三角矩阵来说,大约有一半的元素为零,这些元素不必存储,只需存储下三角部分的非零元素。
三、主要仪器设备计算机一台
4、实验主程序#include<stdio、h>int main(void){int
a[15],b[5][5]={{1},{2,3},{4,5,6},{7,8,9,10},{11,12,13,14, 15}},i,j,k;for(i=0,k=0;i<5;++i)for(j=0;j<=i;++j){a[k]=b[i ][j];++k;} for(i=0;i<15;++i)
printf("%d ",a[i]);
printf("\n");for(i=0;i<5;++i){for(j=0;j<5;++j){if(j<=i)pr intf("%-3d",a[i*(i+1)/2+j]);elseprintf("%-
3d",0);}putchar(\n);}getchar();return 0;}实验结果
五、实验心得通过实验学习,理解了下三角矩阵的压缩存储的算法,了解到像了下三角矩阵这样的规则矩阵可以压缩存储,极大节省了空间,使我受益匪浅。
第 1 页共 1 页。