数组是一堆元素的集合,它没有任何规律,一般通过下标来存取,因此,它也有Hash的功能,其中的下标就是Hash的key。常见的数组有一维数组、二维数组等,二维数组有点类似于矩阵,需要通过行列下标来获取二维数组里的元素。数组非常适合于固定数量的元素,如果涉及到变化的元素,那么链表会是一个不错的选择!
本文将通过以下几方面来介绍数组:
In computer science, an array data structure, or simply an array, is a data structure consisting of a collection of elements (values or variables), each identified by at least one array index or key. An array is stored such that the position of each element can be computed from its index tuple by a mathematical formula.[1][2][3] The simplest type of data structure is a linear array, also called one-dimensional array.
由以上定义可知,数组是有一堆元素组成,每一个元素可以通过一个或多个下标来存取。最简单的数组是一维数组,它的下标编号从0开始,如下图所示:
元素2对应的下标是0,7对应的下标是1,以此类推!通过下标0,可以存取元素2,同理,通过下标2,则可以存取元素1。通过下标来存取某个元素的特性常常被称为随机存取,而为了让数组具备随机存取特性,这就要求存储元素的内容必须是连续的,这就引发了以下几个问题:
因此,与数组相关的操作有:
index
通过下标存取元素append
向数组中追加元素pop
向数组中移除最新追加的元素class Array:
def __init__(self, capacity=10):
self.logical_size = 0
self.capacity = capacity
self.data = [0] * capacity
def append(self, val):
if self.logical_size == self.capacity:
alloc_capacity = 2 * len(self.data)
self.data = self.data + [0] * alloc_capacity
self.capacity += alloc_capacity
self.data[self.logical_size] = val
self.logical_size += 1
def pop(self):
if self.logical_size == 0:
return None
else:
res = self.data[self.logical_size - 1]
self.logical_size -= 1
return res
def index(self, i):
if i < self.logical_size:
return self.data[i]
else:
return None
def print(self):
print(self.data[:self.logical_size])
以下是如何使用上面定义的数组:
one_dim_arr = Array()
one_dim_arr.append(10)
one_dim_arr.append(5)
one_dim_arr.append(106)
one_dim_arr.append(69)
one_dim_arr.pop()
one_dim_arr.append(12)
one_dim_arr.print()
最终的输出结果如下所示:
[10, 5, 106, 12]
接下来,让我们看看以上定义的每一种方法,它们的空间复杂度和时间复杂度是多少。
index
通过下标存取元素,它的空间复杂度是O(1),时间复杂度是O(1)append
向数组中追加元素,如果数组里依然有多余的空间,那么它的空间复杂度是O(1),时间复杂度是O(1),如果数组里没有多余的空间,那么它的空间复杂度是O(n),时间复杂度是O(n)pop
向数组中移除最新追加的元素,它的空间复杂度是O(1),时间复杂度是O(1)数组有它致命的弱点,比如调用append
时,很有可能会发生拷贝行为,除此之外,在数组中间添加元素也会引起拷贝行为,而这些拷贝行为又是非常耗时的。如果你不想让这些拷贝行为发生,那么链表会是一个不错的选择!
{{ c.user.name }}
{{ c.content }}