赞
踩
本篇章主要介绍数组及特殊矩阵,包括数组的基本概念、数组的存储、对称矩阵、三角矩阵、三对角矩阵及稀疏矩阵四种特殊矩阵的压缩。
数组是由
n
(
n
≥
1
)
n(n \geq 1)
n(n≥1)个相同类型的数据元素构成的有限序列,每个数据元素称为一个数组元素,每个元素在
n
n
n个线性关系中的序号称为该元素的下标,下标的取值范围称为数组的维界。
数组是线性表的推广,一维数组可以视为一个线性表,二维数组可以视为其元素也是定长线性表的线性表,以此类推。数组一旦被定义,它的维数和维界就不再改变。因此,除了结构的初始化和销毁之外,数组只有存取元素和修改元素值的操作。
Python中内置的数组是array,但通常使用列表list代替。下面给出列表(没说是数组哦)的一些基本操作:
方法 | 功能 |
---|---|
append(x) | 在列表的末尾添加一个元素 x x x |
clear() | 删除列表中的所有元素 |
copy() | 返回列表的副本 |
count(x) | 返回列表中元素 x x x的个数 |
extend(iterable) | 将列表元素(或任何可迭代的元素)添加到列表的末尾 |
index(x) | 返回元素 x x x的第一个索引 |
insert(index, x) | 在指定位置 i n d e x index index添加元素 x x x |
pop(index) | 删除指定位置 i n d e x index index的元素,默认删除最后一个并返回 |
remove(x) | 删除指定元素 x x x |
reverse() | 反转列表 |
sort(reverse=False, key=myFunc) | 对列表进行排序,默认升序,可以通过参数 k e y key key指定排序标准的函数 |
在Python中最常用的数组运算函数库是numpy,它是一个扩展程序库,在机器学习中超级常用,这里不再叙述,感兴趣的话可以关注或订阅我的机器学习专栏。
由于数组一般不进行插入或删除操作,所以一旦建立了数组,其结构中的数据元素个数和元素之间的关系就不再发生变动,所以数组常采用顺序存储结构来存储数据元素。
一维就是一个线性表,就不多说了,就说一下子多维数组吧,它有按行优先和按列优先两种映射方式。以二维数组(矩阵)为例,按行优先存储的基本思想就是:先行后列,先存储行号较小的元素,行号相等先存储列号较小的元素。
M
=
[
a
11
a
12
a
13
a
21
a
22
a
23
]
M=[a11a12a13a21a22a23]
元素
a
i
j
a_{ij}
aij与在数组中的位置
i
n
d
e
x
index
index对应的关系为
{
i
n
d
e
x
=
(
i
−
1
)
∗
c
o
l
u
m
n
+
(
j
−
1
)
i
=
i
n
d
e
x
/
/
c
o
l
u
m
n
+
1
,
j
=
i
n
d
e
x
%
c
o
l
u
m
n
+
1
{index=(i−1)∗column+(j−1)i=index//column+1,j=index%column+1
对于上述矩阵 M M M,按列优先方式在内存中的存储形式为:
元素
a
i
j
a_{ij}
aij与在数组中的位置
i
n
d
e
x
index
index对应的关系为
{
i
n
d
e
x
=
(
j
−
1
)
∗
r
o
w
+
(
i
−
1
)
i
=
i
n
d
e
x
%
r
o
w
+
1
,
j
=
i
n
d
e
x
/
/
r
o
w
+
1
{index=(j−1)∗row+(i−1)i=index%row+1,j=index//row+1
特殊矩阵是指具有许多相同元素或零元素,并且这些元素的分布有一定规律性的矩阵。
压缩存储是指为多个值相同的元素只分配一个存储空间,对零元素不分配存储空间,其目的是节省存储空间。
特殊矩阵的压缩存储方法是指找出特殊矩阵中值相同的元素的分布规律,把那些呈现规律性分布的、值相同的多个矩阵元素压缩存储到一个存储空间中。
M
=
[
a
11
a
12
…
a
1
n
a
21
a
22
…
a
2
n
⋮
⋮
⋱
⋮
a
n
1
a
n
2
…
a
n
n
]
M=[a11a12…a1na21a22…a2n⋮⋮⋱⋮an1an2…ann]
对于对称矩阵,我们可以为每一对对称元素分配一个存储空间,则可以将
n
2
n^2
n2个元素压缩存储到
n
(
n
+
1
)
2
\frac {n(n+1)} {2}
2n(n+1)个存储空间中。这里用数组
A
A
A来压缩存储矩阵
M
M
M的下三角区的元素,当然,这里还包括对角线上的元素。数组
A
[
k
]
A[k]
A[k]与矩阵
M
M
M中的元素
a
i
j
a_{ij}
aij存在着以下一一对应的关系:
k
=
{
i
(
i
−
1
)
2
+
j
−
1
,
i
≥
j
,
即
下
三
角
区
和
主
对
角
线
j
(
j
−
1
)
2
+
i
−
1
,
i
<
j
,
即
上
三
角
区
k={i(i−1)2+j−1,i≥j,即下三角区和主对角线j(j−1)2+i−1,i<j,即上三角区
k k k | 0 | 1 | 2 | 3 | … \dots … | n ( n + 1 ) 2 − 1 \frac {n(n+1)} {2}-1 2n(n+1)−1 |
---|---|---|---|---|---|---|
a i j a_{ij} aij | a 11 a_{11} a11 | a 21 a_{21} a21 | a 22 a_{22} a22 | a 31 a_{31} a31 | … \dots … | a n n a_{nn} ann |
上面的 k k k是这样算的:第1行有1个元素,第2行有两个元素,第三行有三个元素, … \dots …,第 i − 1 i-1 i−1行有 i − 1 i-1 i−1个元素,第 i i i行有 j − 1 j-1 j−1个元素 ( a i 1 , a i 2 , … , a i j − 1 ) (a_{i1},a_{i2},\dots,a_{ij-1}) (ai1,ai2,…,aij−1),所以 k = 1 + 2 + 3 + ⋯ + ( i − 1 ) + ( j − 1 ) = i ( i − 1 ) 2 + j − 1 k=1+2+3+\dots+(i-1)+(j-1)=\frac {i(i-1)} {2} +j-1 k=1+2+3+⋯+(i−1)+(j−1)=2i(i−1)+j−1。
M
=
[
a
11
a
21
a
22
⋮
⋮
⋱
a
n
1
a
n
2
…
a
n
n
]
M
=
[
a
11
a
12
…
a
1
n
a
22
…
a
2
n
⋱
⋮
a
n
n
]
M=[a11a21a22⋮⋮⋱an1an2…ann]
k
=
{
i
(
i
−
1
)
2
+
j
−
1
,
i
≥
j
,
即
下
三
角
区
和
主
对
角
线
n
(
n
+
1
)
2
,
i
<
j
,
即
上
三
角
区
k={i(i−1)2+j−1,i≥j,即下三角区和主对角线n(n+1)2,i<j,即上三角区
k k k | 0 | 1 | 2 | 3 | … \dots … | n ( n + 1 ) 2 − 1 \frac {n(n+1)} {2}-1 2n(n+1)−1 | n ( n + 1 ) 2 \frac {n(n+1)} {2} 2n(n+1) |
---|---|---|---|---|---|---|---|
a i j a_{ij} aij | a 11 a_{11} a11 | a 21 a_{21} a21 | a 22 a_{22} a22 | a 31 a_{31} a31 | … \dots … | a n n a_{nn} ann | c c c |
如果是存储上三角区的元素,数组的下标 k k k可以这样计算:第1行有 n n n个元素,第2行有 n − 1 n-1 n−1个元素,第3行有 n − 2 n-2 n−2个元素, … \dots …,第 i − 1 i-1 i−1行有 n − i + 2 n-i+2 n−i+2个元素,第 i i i行有 j − i j-i j−i个元素,所以 k = n + ( n − 1 ) + ( n − 1 ) + ⋯ + ( n − i + 2 ) + ( j − i ) = ( i − 1 ) ( 2 n − i + 2 ) 2 + j − i k=n+(n-1)+(n-1)+\dots+(n-i+2)+(j-i)=\frac {(i-1)(2n-i+2)} {2}+j-i k=n+(n−1)+(n−1)+⋯+(n−i+2)+(j−i)=2(i−1)(2n−i+2)+j−i。
M
=
[
a
11
a
12
a
21
a
22
a
23
a
32
a
33
a
34
⋱
⋱
⋱
a
n
−
1
n
−
2
a
n
−
1
n
−
1
a
n
−
1
n
a
n
n
−
1
a
n
n
]
M=[a11a12a21a22a23a32a33a34⋱⋱⋱an−1n−2an−1n−1an−1nann−1ann]
三对角矩阵的压缩存储方式是将3条对角线上的元素按行优先的方式存放在一维数组中,且
a
11
a_{11}
a11存放在
A
[
0
]
A[0]
A[0]中。矩阵
M
M
M中3条对角线上的元素
a
i
j
a_{ij}
aij与一维数组
B
B
B中的下标对应关系如下:
k
=
2
i
+
j
−
3
k=2i+j-3
k=2i+j−3 其中,
1
≤
i
,
j
≤
n
,
∣
i
−
j
∣
≤
1
1\leq i,j\leq n,|i-j|\leq1
1≤i,j≤n,∣i−j∣≤1。
a 11 a_{11} a11 | a 12 a_{12} a12 | a 21 a_{21} a21 | a 22 a_{22} a22 | a 23 a_{23} a23 | … \dots … | a n − 1 n a_{n-1n} an−1n | a n n − 1 a_{nn-1} ann−1 | a n n a_{nn} ann |
---|
如果知道三对角矩阵 M M M中的某个元素 a i j a_{ij} aij存放于一维数组 A A A的第 k k k个位置,则可得 i = ⌊ k + 1 3 + 1 ⌋ , j = k − 2 i + 3 i=\lfloor \frac {k+1} {3} + 1\rfloor,j=k-2i+3 i=⌊3k+1+1⌋,j=k−2i+3。
M
=
[
0
0
0
0
0
3
0
0
0
0
0
0
0
0
0
0
0
0
4
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
11
0
]
M=[0000030000000000004000000000000000000000000110]
由于稀疏矩阵的零元素的分布没有规律,所以在压缩存储稀疏矩阵时,我们不仅要存储非零元素的值,还要存储其所在的行和列,即构成了一个三元组
(
i
,
j
,
a
i
j
)
(i,j,a_{ij})
(i,j,aij)。将上述矩阵
M
M
M以行优先的方式存储:
i i i | j j j | a i j a_{ij} aij |
---|---|---|
0 | 5 | 3 |
2 | 0 | 4 |
4 | 7 | 11 |
矩阵的转置运算,即对于一个
m
×
n
m\times n
m×n的矩阵
M
M
M,其转置矩阵
T
T
T是一个
n
×
m
n\times m
n×m的矩阵,且
T
(
i
,
j
)
=
M
(
j
,
i
)
T(i,j)=M(j,i)
T(i,j)=M(j,i),即行和列所在的位置进行互换。
T
=
[
0
0
4
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
3
0
0
0
0
0
0
0
0
0
0
0
0
0
11
0
0
0
0
0
]
T=[0040000000000000000000000300000000000001100000]
i i i | j j j | a i j a_{ij} aij |
---|---|---|
0 | 2 | 4 |
5 | 0 | 3 |
7 | 4 | 11 |
即行和列交换位置后,再按行优先的方式重新对三元组进行排序。除此之外,稀疏矩阵还可以用十字链表法进行存储,那什么是十字链表呢,这个等介绍到图的存储结构时再说。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。