开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第14天,点击查看活动详情
数据结构
第四章
第二节 数组
定义
按一定格式排列起来的具有相同类型的数据元素的集合。
- 一维数组:若线性表中的数据元素为非结构的简单元素,则称为一维数组。
- 一维数组的逻辑结构:线性结构。定长的线性表。
- 声明格式:数据类型 变量名称[长度];
例如:int arr[5];int arr[5]={1,2,3,4,5};
- 二维数组:若一维数组中的数据元素又是一维数组结构,则称为二维数组。
- 二维数组的逻辑结构:既可以是非线性结构(每一个数据元素既在一个行表中,又在一个列表中,也就是一个元素不止有一个前驱和后继。),又可以是线性结构(每个数据元素也是一个定长的线性表。)
- 声明格式:数据类型 变量名称[行数][列数];
例如:int arr[3][4];在c语言中,一个二维数组类型可以定义为一维数组类型;例如:typedef elementype array2[m][n]==typedef elemtype array1[n] typedef array1 array2[m];
结论
- 线性表结构是数组结构的一个特例,而数组结构又是线性表结构的扩展。
- 数组特点:结构固定——定义后,维数和维界不再改变;
- 数组基本操作:除了结构的初始化和销毁之外,只有取元素和修改元素值的操作。
数组的抽象数据类型
数组的存储结构
由于数组的结构是固定的,也就是维数和维界不变,并且数据基本操作不涉及插入和删除操作,因此一般采用顺序存储结构来表示数组。数组可以是多维的,但是存储数据元素的内存单元地址是一维的; 数组的顺序存储有两种结构:以行为主序,以列为主序; 以行为主序则是如下方式:
例如下面,先存储第一行,再存储第二行...共存储m行
以列为主序则是以下方式:
以行为主序,计算二维数组某个数组元素的位置
假设第一个元素的存储位置用LOC(0,0)表示,存储每个元素需要L个存储单元,那么数组元素a[i][j]的存储位置为:
LOC(i,j)=LOC(0,0)+(i*n+j)*L;
(第一个元素的存储位置+(当前元素前面的所有行 * 每一行的元素个数+当前元素所在行之前的j个元素)*每个元素所占的存储单元).
例题:设有一个二维数组A[m][n]按行优先顺序存储,假设A[0][0]存储位置在644(10),A[2][2]存放位置在676(10),每个元素占一个空间,问A[3][3] (10)存放在什么位置(脚注(10)表示用10进制表示。)
已知A[0][0]的存储位置644(10),A[2][2]的存储位置676(10),因此可以利用如上的计算方式得知:644+(2*n+2)1=676,进而求出n为15。采用同样的计算方式,可得A[3][3]的存储位置:644+(3n+3)*1=644+(3 * 15+3)=692
特殊矩阵的压缩存储
- 矩阵:一个由m*n个元素组成的m行n列的表。
- 矩阵的常规存储:将矩阵描述为一个二维数组。
- 矩阵的常规存储的特点: 可以对其元素进行随机存取; 矩阵运算非常简单;存储的密度为1。 不适宜常规存储的矩阵:值相同的元素很多且呈某种规律分布,零元素多。
- 压缩存储 若多个数据元素的值都相同,则只分配一个元素值的存储空间,且零元素不占存储空间。 一些特殊矩阵,如:对称矩阵,对角矩阵,三角矩阵,稀疏矩阵(矩阵中非零的个数较少,一般小于5%)等。
对称矩阵
特点
在n*n的矩阵中,满足aij=aji(1<i,j<=n)
存储方法
只存储下(或者上)三角(包括主对角线)的数据元素。共占用n(n+1)/2个元素空间。
n(n+1)/2公式得来的计算方式:下三角的数据元素是以等差方式增长的,第一行有1一个元素,第二行有两个元素,第三行有三个元素,以此类推得出1+2+3+4+...+n=n(a1+an)/2=n(n+1)/2,所以上下三角的元素个数都为n(n+1)/2个
以行序为主序将元素存放在一维数组中
例如以行序为主序存储下三角,要计算元素的位置,只需要计算出他之前的元素, 例如a22的元素位置:用i,j表示下标位置,i是行标,j是列标,此时a22 的元素位置为i=1,j=1,那么根据i可得知他之前有i行元素,i行的元素个数就是第一个元素一直到第i个元素位置,1+...+i=i(1+i)/2+1=2
三角矩阵
特点
对角线以下(或以上)的数据元素(不包括对角线)全部为常数C;
存储方法
重复元素c共享一个存储空间,共占用n(n+1)/2+1个元素
位置:sa[1...n(n+1)/2+1]
上三角计算:元素aij前面有i行,那么aij元素位置为n+n-1+n-2+...+i=n(a1+an)/2=n
对角矩阵
特点 在n*n的方阵中,所有非零元素都集中在以主对角线为中心的带状区域中,区域外全为0,则称为对角矩阵。常见的有三对焦矩阵、五对角矩阵、七对角矩阵等。
存储方式
以对角线顺序存储
以主对角线为0,对角线下为1,主对角线上位-1分别存储对应的元素。
稀疏矩阵
稀疏矩阵:设在mn的矩阵中有t个非零元素。 令 a=t/(mn) 当 a<=0.05时称为稀疏矩阵。
如下矩阵,有6行,7列,总共有8个元素,那么计算a=8/(6*7)=19%
由于稀疏矩阵的元素没有任何分布规律,所以在存储非零元素的同时,还要存储下标,因此可以采用三元组法存储,确定每个非零元素的行标和列标以及元素本身
三元组存储方式,头部再加上总行数、总列数、非零元素总个数更直观的展示。同时存储空间要比原来的要小
三元组顺序表又称有序的双下标法。
三元组顺序表的优点:非零元在表中按行序有序存储,因此便于进行依行顺序处理的矩阵计算。
三元组顺序表的缺点:不能随机存取。若按行号存取某一行中的非零元素,需要从头开始查找。
因为稀疏矩阵的元素都是随机存放的,所以我们要查找某一个元素,只能依次遍历,才能找到。
稀疏矩阵的链式存储结构
优点:它能够灵活地插入因运算而产生的新的非零元素,删除因运算而产生的新的零元素,实现矩阵的各种运算。在十字链表中,矩阵地每一个非零元素用一个节点表示,该节点除了(row,col,value)之外,还要有两个域:
- right:用于连接同一行地下一个非零元素;
- down:用于连接同一列地下一个非零元素。
例如以下十字链表存储