一、數組
說動態數組之前,首先要說數組,數組是一種順序存儲的線性表,所有元素的內存地址都是連續的。數組的最大優點是他的查找時間復雜度能夠達到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)