数据结构 第四章 串、数组和广义表 第二节 数组

97 阅读7分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第14天,点击查看活动详情

数据结构

第四章

第二节 数组

定义

一定格式排列起来的具有相同类型的数据元素的集合。

  • 一维数组:若线性表中的数据元素为非结构的简单元素,则称为一维数组。
  • 一维数组的逻辑结构:线性结构。定长的线性表。
  • 声明格式:数据类型 变量名称[长度];

例如:int arr[5];int arr[5]={1,2,3,4,5};

  • 二维数组:若一维数组中的数据元素又是一维数组结构,则称为二维数组。
  • 二维数组的逻辑结构:既可以是非线性结构(每一个数据元素既在一个行表中,又在一个列表中,也就是一个元素不止有一个前驱和后继。),又可以是线性结构(每个数据元素也是一个定长的线性表。) image.png
  • 声明格式:数据类型 变量名称[行数][列数];

例如:int arr[3][4];在c语言中,一个二维数组类型可以定义为一维数组类型;例如:typedef elementype array2[m][n]==typedef elemtype array1[n] typedef array1 array2[m];

结论

  • 线性表结构是数组结构的一个特例,而数组结构又是线性表结构的扩展。
  • 数组特点:结构固定——定义后,维数和维界不再改变;
  • 数组基本操作:除了结构的初始化和销毁之外,只有取元素和修改元素值的操作。

数组的抽象数据类型

image.png

数组的存储结构

由于数组的结构是固定的,也就是维数和维界不变,并且数据基本操作不涉及插入和删除操作,因此一般采用顺序存储结构来表示数组。数组可以是多维的,但是存储数据元素的内存单元地址是一维的; 数组的顺序存储有两种结构:以行为主序,以列为主序; 以行为主序则是如下方式:

例如下面,先存储第一行,再存储第二行...共存储m行

image.png

以列为主序则是以下方式:

image.png

以行为主序,计算二维数组某个数组元素的位置

image.png 假设第一个元素的存储位置用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) image.png 存储方法 只存储下(或者上)三角(包括主对角线)的数据元素。共占用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个

image.png

以行序为主序将元素存放在一维数组中

例如以行序为主序存储下三角,要计算元素的位置,只需要计算出他之前的元素, 例如a22的元素位置:用i,j表示下标位置,i是行标,j是列标,此时a22 的元素位置为i=1,j=1,那么根据i可得知他之前有i行元素,i行的元素个数就是第一个元素一直到第i个元素位置,1+...+i=i(1+i)/2+1=2 image.png

三角矩阵

特点 对角线以下(或以上)的数据元素(不包括对角线)全部为常数C; image.png 存储方法 重复元素c共享一个存储空间,共占用n(n+1)/2+1个元素 位置:sa[1...n(n+1)/2+1]

image.png

上三角计算:元素aij前面有i行,那么aij元素位置为n+n-1+n-2+...+i=n(a1+an)/2=n

对角矩阵

特点 在n*n的方阵中,所有非零元素都集中在以主对角线为中心的带状区域中,区域外全为0,则称为对角矩阵。常见的有三对焦矩阵、五对角矩阵、七对角矩阵等。

image.png 存储方式 以对角线顺序存储 以主对角线为0,对角线下为1,主对角线上位-1分别存储对应的元素。 image.png

稀疏矩阵

稀疏矩阵:设在mn的矩阵中有t个非零元素。 令 a=t/(mn) 当 a<=0.05时称为稀疏矩阵。

如下矩阵,有6行,7列,总共有8个元素,那么计算a=8/(6*7)=19%

image.png image.png 由于稀疏矩阵的元素没有任何分布规律,所以在存储非零元素的同时,还要存储下标,因此可以采用三元组法存储,确定每个非零元素的行标和列标以及元素本身

三元组存储方式,头部再加上总行数、总列数、非零元素总个数更直观的展示。同时存储空间要比原来的要小

image.png 三元组顺序表又称有序的双下标法。 三元组顺序表的优点:非零元在表中按行序有序存储,因此便于进行依行顺序处理的矩阵计算。 三元组顺序表的缺点:不能随机存取。若按行号存取某一行中的非零元素,需要从头开始查找。

因为稀疏矩阵的元素都是随机存放的,所以我们要查找某一个元素,只能依次遍历,才能找到。

稀疏矩阵的链式存储结构
优点:它能够灵活地插入因运算而产生的新的非零元素,删除因运算而产生的新的零元素,实现矩阵的各种运算。在十字链表中,矩阵地每一个非零元素用一个节点表示,该节点除了(row,col,value)之外,还要有两个域:

  • right:用于连接同一行地下一个非零元素;
  • down:用于连接同一列地下一个非零元素。

image.png

例如以下十字链表存储

image.png