数据结构(五)数组及特殊矩阵的压缩存储
特殊矩阵的压缩存储
数组
数组可以看作线性表的推广。数组作为一种数据结构其特点是结构中的元素本身可以是具有某种结构的数据,但属于同一数据类型,数组是一个具有固定格式和数量的数据有序集, 每一个数据元素有唯一的一组下标来标识,因此,在数组上不能做插入、删除数据元素的操作。
1、数组的定义和运算
( 1 )数组的定义
从逻辑结构上,数组可以看成是一般线性表的扩充。一维数组即为线性表, 而二维数组可以定义为“其数据元素为一维数组(线性表)”的线性表。依此类推, 即可得到多维数组的定义。N 维数组是“数据元素为 N-1 维数组”的线性表。
由数组结构可以看出,数组中的每一个元素由一个值和一组下标来描述。 “值”代表数组中元素的数据信息,一组下标用来描述该元素在数组中的相对位 置信息。数组的维数不同,描述其相对位置的下标的个数也不同。
( 2 )数组的运算
数组是一组有固定个数的元素的集合。即,一旦定义了数组的维数和每一维的上、下限,数组中元素的的个数就固定了。例如二维数组 A3 × 4 ,它有 3 行、 4 列,即由 12 个元素组成。由于这个性质,使得对数组的操作不像对线性表的操作 那样可以在表中任意一个合法的位置插入或删除一个元素。对于数组的操作一般只有两类: ①获得特定位置的元素值; ②修改特定位置的元素值。 因此数组的操作主要是数据元素的定位,即给定元素的下标,得到该元素在计算机中的存放位置。其本质上就是地址计算问题。
( 3 )数组的抽象数据类型定义
数组的抽象数据类型定义如下: ADT Array{
注意:这里定义的数组与 C 语言的数组略有不同,下标统一从 1 开始。
2、数组的顺序存储
通常在各种高级语言中数组一旦被定义,每一维的大小及上下界都不能改变。
通常,数组在内存被映象为向量,即用向量作为数组的一种存储结构,这是因为内存的地址空间是一维的,数组的行列固定后,通过一个 映象函数,则可根据数组元素的下标得到它的存储地址。
对于一维数组按下标顺序分配即可。对多维数组分配时,要把它的元素映象存储在一维存储器中,一般有两种存储方式:一是以行为主序(或先行后列)的顺序存放,另一种是以列为主序(先列后行)的顺序存放。
设有 m×n 二维数组 Amn,下面我们看按元素的下标求其地址的计算:
以“以行为主序”的分配为例:设数组的基址为 LOC(a11),每个数组元素占据 d 个地址单 元,那么 aij 的物理地址可用一线性寻址函数计算:
LOC(aij) = LOC(a11) + ( (i-1)*n + j-1 ) * d
这是因为数组元素 aij的前面有 i-1 行,每一行的元素个数为 n,在第 i 行中它的前面还有 j-1 个数组元素。
在 C 语言中,数组中每一维的下界定义为 0,则: LOC(aij) = LOC(a00) + ( i*n + j ) * d 推广到一般的二维数组:A[c1...d1][c2...d2],则 aij的物理地址计算函数为:
LOC(aij)=LOC(a c1 c2)+( (i- c1) *( d2 - c2 + 1)+ (j- c2) )d
规律分布特殊矩阵的压缩存储
规律分布的特殊矩阵
元素分布具有一定规律的矩阵称为规律分布的特殊矩阵,如三角矩阵(方阵的上或下三 角全为零)和带状矩阵(若干条对角线含有非零元)。这类矩阵中元素分布的规律可以用数学公式来反映。
已知二维矩阵 A 中元素下标 i 和 j,作为转换函数 f 的自变量,计算出到一维内存空间的地址值 K,即 A i=B[ K],实现了原二维矩阵到压缩存储后的一维数组的存储映射。
1 .三角矩阵
三角矩阵大体分为三类:下三角矩阵、上三角矩阵、对称矩阵;对于一个 n 阶矩阵 A 来 说:
(1)若当 i <j 时,有 aij =c(典型情况 c=0 ),则称此矩阵为上三角矩阵;
将上三角矩阵A[1...n][1...n]存放在一维数组B[n(n+1)/2+1]中,即元素aij存放在bk中。
在数组B中,位于元素aij(i<=j)前面的元素个数为:第一行(n个元素)第二行(n-1个元素)......第i-1行(n-i+2个元素)第i行(j-i个元素);
因此,元素aij在数组B中的下标 k=n+n-1+...+(n-i+2)+(j-i+1)-1 = (i-1)(2n-i+2)/2+(j-i)(数组下表从0开始),元素下标之间的对应关系如下:
(2)若当 i>j 时,有 aij =c(典型情 况 c=0 ),则称此矩阵为下三角矩阵;
将下三角矩阵A[1...n][1...n]压缩存储在一维数组B[n(n+1)/2+1]中(数组下表从0开始),元素下标之间的对应关系如下:
(3)若矩阵中的所有元素均满足 aij =aji,则称此矩阵为对称矩阵;
将对称矩阵A[1...n][1...n]存放在一维数组B[n(n+1)/2]中,即元素aij存放在bk中,只存放下三角部分(含对角线)的元素。
在数组B中,位于元素aij(i>=j)前面的元素个数为:第一行(1个元素a11)第二行(2个元素a21,a22)......第i-1行(i-1个元素ai-1,1,ai-1,2,...,ai-1,i-1)第i行(j-1个元素ai1,ai2,...,ai,j-1);
因此,元素aij在数组B中的下标 k=1+2+...+(i-1)+j-1 = i(i-1)/2+j-1(数组下表从0开始),元素下标之间的对应关系如下:
2 .带状矩阵
( 1 )带状矩阵描述:在矩阵中的所有非零元素都集中在以主对角线为中心的带状区域中。
( 2 )三对角带状矩阵特点
( 3 )三对角带状矩阵压缩存储方法
三对角带状矩阵的压缩存储原则为:将带状区域上的非零元素按行序存储。
其压缩存储方法如下:
①确定存储该矩阵所需的一维向量空间的大小:假设每个非零元素所占空间的大小为 size 个单元。在三对角带状矩 阵中,除了第一行和最后一行只有2个非零元素外,其余各行均有3个非零元素,由此得到:所需 一维向量空间的大小为: 2 +2 +3 ×( n-2 )= 3n-2 。
②确定非零元素在一维数组空间中的地址 Loc ( A i)= Loc ( A1)+(前 i-1 行非零元素个数+第 i 行中 aij 前非零元素个 数)*size, 前 i-1 行元素个数=3 ×( i-1 )- 1 (因为第 1 行只有 2 个非零元素); 第 i 行中 aij 前非零元素个数=j-i +1 ,其中
由此得到: Loc ( A i)= Loc( A1)+( 3 ( i-1 )- 1 +j-i +1)*size = Loc( A1)+( 2 ( i-1 )+ j -1)*size (按行优先存放)
稀疏矩阵
仅存储非零元素,还需要存储它所在的行和列,构成三元组;稀疏矩阵压缩存取后失去了随机存取特性。
稀疏矩阵的三元组既可以采用数组存储,也可以采用十字链表法存储。