[数据结构] 数组和特殊矩阵的存储

数组的存储

一维数组

  • 数组名实际上就是数组首地址,是一个地址常量,本质上是一个数
  • 数组名也可以进行运算,是逻辑上的运算,并不是直接的数字运算
  • arr[0]和*arr是一样的
  • *(arr+1)和arr[1]是一样的
  • arr和&arr[0]是一样的
  • 数组存储空间时连续的,是线性的,所以算地址的时候可以用等差数列的公式a[n]地址=a[m]地址+(n-m)*元素占用空间

例证:

#include

int main(void)
{
	char arr1[5] = {'a','b','c','d','e'};
	printf("%d\n",arr1);
	printf("%d\n",&arr1[0]);
	printf("%d\n",*arr1);
	printf("%d\n",arr1[0]);
	printf("%d\n",arr1 + 1);
	printf("%d\n",arr1[1]);
	printf("%d\n",*(arr1 + 1));

	int arr2[5] = {1,2,3,4,5};
	printf("%d\n",arr2);
	printf("%d\n",arr2 + 1);
	printf("%d\n",*(arr2 + 1));
	printf("%d\n",arr2[1]);
	return 0;
}

[数据结构] 数组和特殊矩阵的存储_第1张图片

二维数组

  • 二维数组就是每个元素都是一维数组,即arr[0],arr[1]都是数组
  • arr[0]表示第一个数组的首地址,arr[1]是第二个数组的首地址
  • 同理arr和arr[0]是一样的;*(arr + 1)和arr[1]是一样的
  • *(arr[0]+1)表示arr[0][1]
  • *(*(arr+1)+1)等价于*(arr[1]+1)等价于arr[1][1]

例证:

#include

int main(void)
{
	int arr[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
	printf("%d\n",arr);
	printf("%d\n",arr + 1);
	printf("%d\n",*(*arr + 1));
	printf("%d\n",*(arr[0] + 1));
	printf("%d\n",*(*(arr+1) + 1));
	printf("%d\n",*(arr[1] + 1));
	return 0;
}

[数据结构] 数组和特殊矩阵的存储_第2张图片

数组的存储结构

一维数组

数组都是顺序存储的,一个挨着一个,比如int a[5] = {1,2,3,4,5}。int占四个字节,a[0]和a[1]连续,因此差4个字节。根据等差数列通项公式,有

Loc(a[i]) = Loc(a[j]) + (i-j)*size

二维数组

二维数组也是顺序存储的,但是可以按照行存储,也可以按照列存储。算法和上面类似,主要是看差距多少个元素。比如数组a[3][5],那么a[1][1]和a[2][3]差距多少呢?如果按照行存储,也就是一行一行存,那么差2-1=1行,一行5个数,在加上3-1=2,共差7个元素,所以a[2][3]地址等于a[1][1]地址加上7乘以元素size

特殊矩阵压缩存储

  • 对称矩阵:用一维数组只存放上三角或者下三角矩阵
  • 上三角矩阵或下三角矩阵:用一维数组存
  • 三对角矩阵:一维数组存
  • 稀疏矩阵:用三元组(行标,列号,数值)外加(总行数,总列数,非零元素个数)存

对称矩阵

对于一个对称矩阵,假设张下面这样

[数据结构] 数组和特殊矩阵的存储_第3张图片

因为是对称的,所以只存上三角或者下三角就够了,原来一共n*n个元素,用一维数组存只需要1+2+3+4+...+n个元素就够了。

假设存下三角区域,那么第i行第j列是一维数组中第几个元素呢?

第i行第j列(i>=j),1+2+3+4+...+(i-1)+j

可以这么想,第i行第j列前边有几个元素?第一行1个,第二行2个,第i行第j列,前边有i-1行,所以前边有1+2+3+...(i-1)个,再看本行,前边有j-1个,所以这个元素前边有1+2+3+4+...+(i-1)+j-1个元素,所以这个元素是第1+2+3+4+...+(i-1)+j个,如果数组是从0开始,那么下标就是1+2+3+4+...+(i-1)+j-1,那么i<=j的时候就把i和j交换下就行。

下三角矩阵

计算方法和上面类似,一维数组长度是(1+2+3+4+...+n)+1,为啥要加1,因为三角矩阵另一个角是个常数(一般是0,当然也可以是别的)。同理,i>=j时,第i行第j列前边共有1+2+3+4+...+(i-1)+j-1个元素,所以这个元素是第1+2+3+4+...+(i-1)+j个,当i

上三角矩阵

上三角和上面类似,一维数组长度仍然是(1+2+3+4+...+n)+1,只是第一行有n个,第2行有n-1个,第i行有n-i+1个,当i<=j时,前边有[n+(n-1)+(n-2)+...+(n-(i-1)+1)]+(j-i)个元素,所以这个元素是第[n+(n-1)+(n-2)+...+(n-(i-1)+1)]+(j-i)+1个。当i>j时,即是下三角区域,就存到最后,即第(1+2+3+4+...+n)+1个元素。

稀疏矩阵

对于稀疏矩阵(大多数元素是0的),只存储非零元素,比如这个矩阵就是这么存的。

[数据结构] 数组和特殊矩阵的存储_第4张图片

当然,还要存储数组的行数,列数和非零元素个数,如下

[数据结构] 数组和特殊矩阵的存储_第5张图片

三对角矩阵

三对角矩阵长这样子:

[数据结构] 数组和特殊矩阵的存储_第6张图片

只存储主对角线及其上、下两侧次对角线上的元素,其他的零元素一律不存储。对一个n*n的三对角方阵A,元素总数有n*n个,而其中非零的元素共有3*n-2个。因此,存储三对角矩阵时最多只需存储3*n-2个元素。

[数据结构] 数组和特殊矩阵的存储_第7张图片

这个不是很好找规律,由于是线性的,可以用待定系数法求出。

你可能感兴趣的:(数据结构)