什么是数组❓
数组是由 n ( n ⩾ 1 ) n(n\geqslant1) n(n⩾1)个相同类型的数据元素的有限序列。
除了定义还需认识一些知识点:
数组与线性表的关系
由于数组在物理上是连续存储的,所以只要知道数组的起始地址、数据类型,就可以算出其存储位置
若一维数组A[n]
,则其存储结构关系式为:
数组下标从0开始:LOC(A[i]) = LOC(A[0])+i*sizeof(ElemType) (0<=i<n-1)
数组下标从1开始:LOC(A[i]) = LOC(A[1])+(i-1)*sizeof(ElemType) (1<=i<n)
小试牛刀
题目描述:
一维数组A[0...n]
采用顺序存储结构,每个元素占用4个字节,该数组的首地址为120,求A[4]
的存储地址( )
✅正确答案:136
题目解析:
注意数组下标是从0
开始的
如图:
第一个4:0—4之间一共有四个元素
第二个4:该数组是int类型,字节为4B
对于多维数组,有两种映射方法:按行优先、按列优先
按行存储
基本思想:
先行后列
,先存储行号比较小的元素,行号相等先存储列号比较小的元素。
设二维数组A[m][n]
,则存储结构关系式为:
数组下标从0开始:LOC(A[i,j]) = LOC(A[0,0])+(i*n+j)*sizeof(ElemType)
数组下标从1开始:LOC(A[i,j]) = LOC(A[1,1])+[(i-1)*n+j]*sizeof(ElemType)
小试牛刀
题目描述:
假设二维数组A[3,4]
每个元素占用2个存储单元,数组元素(A[0][0]
)的起始地址为1000,求数组元素A[2][2]
的起始地址。
✅正确答案:1020
题目解析:
注意数组下标是从0
开始的
公式求解:LOC(A[2,2]) = LOC(A[0,0])+(2*4+2)*2=1000+20=1020
图解:
列优先(原理同上)
基本思想:
先列后行
,先存储列号比较小的元素,列号相等先存储行号比较小的元素。
设二维数组A[m][n]
,则存储结构关系式为:
数组下标从0开始:LOC(A[i,j]) = LOC(A[0,0])+(j*n+i)*sizeof(ElemType)
数组下标从1开始:LOC(A[i,j]) = LOC(A[1,1])+[(j-1)*n+i]*sizeof(ElemType)
1. 压缩矩阵:指为多个值相同的元素分配一个存储空间,对零元素不分配存储空间。其目的是节省存储空间
2. 特殊矩阵:值具有许多相同矩阵元素或零元素,并且这些相同矩阵元素或零元素的分布有一定规律性的矩阵。常见特殊矩阵有对称矩阵、上(下)三角矩阵、对角矩阵等。
3. 特殊矩阵的压缩存储方法:找到特殊矩阵中值相同的矩阵元素的分布规律,把那些呈现规律性分布的、值相同的多个矩阵元素压缩到一个存储空间中。
对称矩阵为何不能用二维矩阵存储❓
对于n阶对称矩阵,上三角元素的所有元素和下三角区对应的元素相同,若扔采用二维数组存放,则会浪费一半的空间,对此将对称矩阵存放在一维数组中。
那么如何将二维数组存储于一维数组❓
思考1:有多少个二维元素
A[0...n-1][0...n-1]
存于一维元素中❓
由于上三角区==下三角区
,只需要在一维数组中存储主对角线+下三角区
第 1 行(A[0]):1 个元素 第 2 行(A[1]):2 个元素 第 3 行(A[2]):3 个元素 ...... 第 n 行(A[n-1]):n个元素(❗由于数组从0开始,A[0]占了一行,所以A[n]是第n-1行) 共:1+2+3+...+n=[1+n]*n/2=(n+1)*n/2
✅答案:一维数组共需存储 ( n + 1 ) ∗ n 2 \frac {(n+1)*n} 2 2(n+1)∗n个元素
思考2:按行排列,二维数组A[0…n-1][0…n-1]与一维数组B[0… ( n + 1 ) ∗ n 2 − 1 \frac {(n+1)*n} 2-1 2(n+1)∗n−1]对应的关系❓
- 求
A[1][1]
在一维数组B[0… ( n + 1 ) ∗ n 2 − 1 \frac {(n+1)*n } 2-1 2(n+1)∗n−1]的位置:A[1][1]位于第2行的第2列 第1行:共1个元素 第2行:有2个元素 求和:1+2=3 B的下标从0开始,所以3-1=2,即A[1][1]`在一维数组B[2]中
- 求
A[2][1]
在一维数组B[0… ( n + 1 ) ∗ n 2 − 1 \frac {(n+1)*n} 2-1 2(n+1)∗n−1]的位置:A[2][1]位于第3行的第2列 第1行:共1个元素 第2行:共2个元素 第3行:有2个元素 求和:1+2+3=5 B的下标从0开始,所以5-1=4,即A[2][1]`在一维数组B[4]中
- 求
A[i][j]
在一维数组B[0… ( n + 1 ) ∗ n 2 − 1 \frac {(n+1)*n } 2-1 2(n+1)∗n−1]的位置:A[i][j]位于第i+1行的第j+1列 第 1 行:共 1 个元素 第 2 行:共 2 个元素 第 3 行:共 3 个元素 ... 第 i 行:共 i 个元素 第i+1行:有j+1个元素 求和:1+2+3+...+i+(j+1)=(i+1)*i/2+(j+1) B的下标从0开始,所以(i+1)*i/2+(j+1)-1=(i+1)*i/2+j,即A[i][j]`在一维数组B[(i+1)*i/2+j]中
✅答案:按行排序,二位数组
A[i][j]
与一维数组B[ ( i + 1 ) ∗ i 2 + j \frac {(i+1)*i} 2+j 2(i+1)∗i+j]对应
思考3:按列排列,二维数组A[0…n-1][0…n-1]与一维数组B[0… ( n + 1 ) ∗ n 2 − 1 \frac {(n+1)*n } 2-1 2(n+1)∗n−1]对应的关系❓
- 求
A[1][1]
在一维数组B[0… ( n + 1 ) ∗ n 2 − 1 \frac {(n+1)*n } 2-1 2(n+1)∗n−1]的位置:A[1][1]位于第2行的第2列 第1列:共n-1个元素 第2列:有1个元素 求和:n-1+1=n B的下标从0开始,所以n-1=(n-1),即A[1][1]`在一维数组B[n-1]中
- 求
A[2][1]
在一维数组B[0… ( n + 1 ) ∗ n 2 − 1 \frac {(n+1)*n} 2-1 2(n+1)∗n−1]的位置:A[2][1]位于第3行的第2列 第1列:共n-1个元素 第2列:共2个元素 求和:n-1+2=n+1 B的下标从0开始,所以n+1-1=n,即A[2][1]`在一维数组B[n]中
- 求
A[i][j]
在一维数组B[0… ( n + 1 ) ∗ n 2 − 1 \frac {(n+1)*n } 2-1 2(n+1)∗n−1]的位置:A[i][j]位于第i+1行的第j+1列 第 1 列:共 n-1 个元素 第 2 列:共 n-2 个元素 第 3 列:共 n-3 个元素 ... 第 j 列:共 n-j 个元素 第j+1列:有i+1-j个元素 求和:(n-1)+(n-2)+(n-3)+...+(n-j)+(i+1-j)=(n-1+n-j)*j/2+i+1-j=(2n-1-j)*j/2+i+1-j B的下标从0开始,所以(2n-1-j)*j/2+i+1-j-1=(2n-1-j)*j/2+i-j,即A[i][j]在一维数组B[(2n-1-j)*j/2+i-j]中
✅答案:按列排序,二位数组
A[i][j]
与一维数组B[ ( ( 2 n − 1 − j ) ∗ j 2 + i − j \frac {((2n-1-j)*j} 2+i-j 2((2n−1−j)∗j+i−j]对应
思考4:思考二、三都是以下三角区为例,那么上三角区如何存储❓
由图可知,上三角区与下三角区的关系为:A[i][j]==A[j][i]
所以:
- 上按行==下按列,二位数组
A[i][j]
与一维数组B[ ( ( 2 n − 1 − i ) ∗ i 2 + j − i \frac {((2n-1-i)*i} 2+j-i 2((2n−1−i)∗i+j−i]对应- 上按列==上按排,二位数组
A[i][j]
与一维数组B[ ( j + 1 ) ∗ j 2 + i \frac {(j+1)*j} 2+i 2(j+1)∗j+i]对应
三角矩阵是什么❓
三角矩阵可以分为上三角矩阵和下三角矩阵
三角矩阵如何存储❓
思考5:有多少个二维元素
A[0...n-1][0...n-1]
存于一维元素中❓以下三角矩阵为例:
三角矩阵与对称矩阵的存储方式相似,不同之处在于,)存储完下三角区和主对角线后,紧接着存储上三角区的常量一次
由对称矩阵可知,下三角区+主对角线的元素=(n+1)*n /2个元素 三角矩阵多了一个常量:所以共有(n+1)*n /2+1个元素
✅答案:一维数组共需存储 ( n + 1 ) ∗ n 2 + 1 \frac {(n+1)*n} 2+1 2(n+1)∗n+1个元素
思考6:下三角矩阵如何存储❓
- 三角矩阵的
下三角区+主对角线
与对阵矩阵存储相同,可直接使用思考二的结论.- 三角矩阵的
上三角区的常量
存于一维数组的最后,所以位置固定: ( n + 1 ) ∗ n 2 \frac {(n+1)*n} 2 2(n+1)∗n
✅答案:按行排序,二维数组
A[i][j]
与B[k]
相对应,其中 k = { ( i + 1 ) ∗ i 2 + j ( 下和主元素 ) ( n + 1 ) ∗ n 2 + 1 ( 上元素 ) k= \begin{cases} {\frac {(i+1)*i} 2+j} (下和主元素) \\ \\ \frac {(n+1)*n} 2+1(上元素) \end{cases} k=⎩ ⎨ ⎧2(i+1)∗i+j(下和主元素)2(n+1)∗n+1(上元素)
- 三角矩阵的
下三角区+主对角线
与对阵矩阵存储相同,可直接使用思考三的结论.- 三角矩阵的
上三角区的常量
存于一维数组的最后,所以位置固定: ( n + 1 ) ∗ n 2 \frac {(n+1)*n} 2 2(n+1)∗n
✅答案:按行排序,二维数组
A[i][j]
与B[k]
相对应,其中 k = { ( ( 2 n − 1 − j ) ∗ j 2 + i − j ( 下和主元素 ) ( n + 1 ) ∗ n 2 + 1 ( 上元素 ) k= \begin{cases} {\frac {((2n-1-j)*j} 2+i-j} (下和主元素) \\ \\ \frac {(n+1)*n} 2+1(上元素) \end{cases} k=⎩ ⎨ ⎧2((2n−1−j)∗j+i−j(下和主元素)2(n+1)∗n+1(上元素)
思考7:上三角矩阵如何存储❓
- 三角矩阵的
上三角区+主对角线
与对阵矩阵存储相同,可直接使用思考四的结论.- 三角矩阵的
下三角区的常量
存于一维数组的最后,所以位置固定: ( n + 1 ) ∗ n 2 \frac {(n+1)*n} 2 2(n+1)∗n
✅答案:按行排序,二维数组
A[i][j]
与B[k]
相对应,其中 k = { ( ( 2 n − 1 − i ) ∗ i 2 + j − i ( 上和主元素 ) ( n + 1 ) ∗ n 2 + 1 ( 下元素 ) k= \begin{cases} {\frac {((2n-1-i)*i} 2+j-i} (上和主元素) \\ \\ \frac {(n+1)*n} 2+1(下元素) \end{cases} k=⎩ ⎨ ⎧2((2n−1−i)∗i+j−i(上和主元素)2(n+1)∗n+1(下元素)
按列存储
知:
- 三角矩阵的
上三角区+主对角线
与对阵矩阵存储相同,可直接使用思考四的结论.- 三角矩阵的
下三角区的常量
存于一维数组的最后,所以位置固定: ( n + 1 ) ∗ n 2 \frac {(n+1)*n} 2 2(n+1)∗n
✅答案:按行排序,二维数组
A[i][j]
与B[k]
相对应,其中 k = { ( j + 1 ) ∗ j 2 + i ( 上和主元素 ) ( n + 1 ) ∗ n 2 + 1 ( 下元素 ) k= \begin{cases} {\frac {(j+1)*j} 2+i} (上和主元素) \\ \\ \frac {(n+1)*n} 2+1(下元素) \end{cases} k=⎩ ⎨ ⎧2(j+1)∗j+i(上和主元素)2(n+1)∗n+1(下元素)
三对角矩阵是什么❓
三对角矩阵如何存储❓
思考8:有多少个二维元素
A[0...n-1][0...n-1]
存于一维元素中❓由上图可知,除了第一行和最后一行为两个元素,其他每行都为三个元素,共有
3*n-2
个元素
✅答案:一维数组共需存储 3 ∗ n − 2 3*n-2 3∗n−2个元素
思考9:按行排序,二维数组
A[0...n-1][0...n-1]
与一维数组B[0...3n-3]
对应的关系❓
A[i][j]
在一维数组B[0...3n-3]
的位置:A[i][j]位于第i+1行的第j+1列 第 1 行:共 2 个元素 第 2 行:共 3 个元素 第 3 行:共 3 个元素 ... 第 i 行:共 3 个元素 第i+1行:有j-i+2个元素 求和:2+3+3+...+3+j-i+2=(3i-1)+j-i+2=2i+j+1 B的下标从0开始,所以2i+j+1-1=2i+j,即A[i][j]在一维数组B[2i+j]中
✅答案:按行排序,二位数组
A[i][j]
与一维数组B[2i+j]
对应
思考10:按列排序,二维数组
A[0...n-1][0...n-1]
与一维数组B[0...3n-3]
对应的关系❓
A[i][j]
在一维数组B[0...3n-3]
的位置:A[i][j]位于第i+1行的第j+1列 第 1 列:共 2 个元素 第 2 列:共 3 个元素 第 3 列:共 3 个元素 ... 第 j 列:共 3 个元素 第j+1列:有i-j+2个元素 求和:2+3+3+...+3+i-j+2=(3j-1)+i-j+2=2j+i+1 B的下标从0开始,所以2j+i+1-1=2j+i,即A[i][j]在一维数组B[2j+i]中
✅答案:按列排序,二位数组
A[i][j]
与一维数组B[2j+i]
对应
《王道:23数据结构考研复习指导》