一、数组
说动态数组之前,首先要说数组,数组是一种顺序存储的线性表,所有元素的内存地址都是连续的。数组的最大优点是他的查找时间复杂度能够达到O(1),但是增和删的时间复杂度较高O(n)
二、动态数组
动态数组,即根据用户的输入动态扩充或缩小当前数组的容量。在python中,已经内置了动态数组,叫做列表,List
下面是利用python代码实现动态数组的增删改查操作。
# ArrryList.py
class Arr:
# 设置两个常亮,分别是默认容量大小与未找到元素返回的值
DEFAULT_CAPACITY = 10
ELEMENT_NOT_FOUND = -1
# 初始化,若用户未指定数组大小或者小于默认,直接使用默认容量,否则容量为用户指定
def __init__(self, capacity=DEFAULT_CAPACITY):
capacity = self.DEFAULT_CAPACITY if capacity < self.DEFAULT_CAPACITY else capacity
self._capacity = capacity
self._size = 0
self._elements = [None] * self._capacity
def size(self):
return self._size
def is_empty(self):
# return True if self._size == 0 else False
# 改进上面这还代码,因为在python中所有值都可以转布尔,所以利用隐式布尔值
return self._size == 0
# 查看元素是否存在--->bool
def contains(self, element):
# if self.index_of(element):
# return True
# return False
return True if self.index_of(element) else False
# 根据索引添加,添加结束后判断是否需要扩容
def add(self, index, element):
self._out_of_index(index)
self._size = i = self._size + 1
while i >= index:
self._elements[i] = self._elements[i - 1]
i -= 1
self._elements[index] = element
self._expend_capacity()
# 数组末尾追加,添加结束后判断是否需要扩容
def add_last(self, element):
self._out_of_index(self._size)
self._elements[self._size] = element
self._size += 1
self._expend_capacity()
# 根据索引取值
def get(self, index):
self._out_of_index(index)
return self._elements[index]
# 根据索引改值
def set(self, index, element):
self._out_of_index(index)
self._elements[index] = element
# 删除元素,若用户未指定参数,默认删除最后一个元素,删除后判断是否要缩容
def remove(self, index=ELEMENT_NOT_FOUND):
self._out_of_index(index)
if index == self.ELEMENT_NOT_FOUND:
self._remove_last()
# 删除元素后,该索引后的每个元素都要往前移一格,然后数组大小减一
i = index
while i <= self._size:
self._elements[i] = self._elements[i + 1]
i += 1
self._size -= 1
self._reduce_capacity()
# 返回第一个匹配传入值的索引
def index_of(self, element):
for index in range(self._size + 1):
if element == self._elements[index]:
return index
return self.ELEMENT_NOT_FOUND
def clear(self):
self._size = 0
return self._size
# 判断索引是否越界
def _out_of_index(self, index):
if index < 0 or index > self._size + 1:
raise IndexError('index out of range')
# 当容量不够时动态扩容,默认为扩大为原来的1.5倍
def _expend_capacity(self):
# 当size小于容量,直接返回,当size正好等于容量,需要扩容
if self._size < self._capacity - 1:
return
self._capacity = self._capacity * 2
self._new_elements = [None] * self._capacity
for i in range(self._size):
self._new_elements[i] = self._elements[i]
self._elements = self._new_elements
# 动态缩容,默认缩小到当前的一半
def _reduce_capacity(self):
# 当size小于默认容量或者大于当前容量的一半时直接返回
if self._size <= self._capacity or self._size > (self._capacity // 2):
return
self._capacity = (self._capacity // 2).__ceil__()
for i in range(self._size):
self._new_elements[i] = self._elements[i]
self._elements = self._new_elements
def __str__(self):
arrlist = ''
num = 0
for i in self._elements:
if num == self._size:
break
arrlist = arrlist + str(i) + ','
num += 1
arrlist = arrlist.strip(",")
arrlist = '[' + arrlist + ']'
return arrlist
"""
删除最后一个元素,因为最后一个元素也是往前移动一格,虽然size-1,但是其实最后一个元素引用了两次,
即当前的数组末尾加上原来位置的引用,无法回收,所以对于最后一个元素要手动设置为None
"""
def _remove_last(self):
self._size -= 1
self._elements[self._size] = None
self._reduce_capacity()
# 测试文件,test.py
if __name__ == '__main__':
from ArrayList import Arr
a = Arr()
# a = a #type:Arr
a.add_last(11)
a.add_last(22)
a.add_last(33)
a.add_last(44)
a.add_last('55')
a.add_last(66)
a.add_last(77)
a.add_last(88)
a.add_last(99)
# a.add(2,'st')
# a.remove(2)
# print(a.size())
# print(a.is_empty())
# print(a.contains('55'))
# print(a.index_of(99))
# print(a.get(789))
# a.set(-1,99)
# a.clear()
print(a)