1.数组数据结构
class Array(object):
def __init__(self, capacity, fileValue=None):
"""
:param capacity: 数组容量的大小
:param fileValue: 数组每个位置的值
"""
self._items = list()
for count in range(capacity):
self._items.append(fileValue)
def __len__(self):
"""
数组容量的大小
"""
return len(self._items)
def __str__(self):
"""
数组的字符串表示形式
"""
return str(self._items)
def __iter__(self):
"""
支持遍历for循环
"""
return iter(self._items)
def __getitem__(self, index):
"""
用于索引访问的下标运算符
"""
return self._items[index]
def __setitem__(self, index, newItem):
"""
在索引处替换的下标运算符
"""
self._items[index] = newItem
a = Array(10)
len(a)
print(a)
for i in range(len(a)):
a[i] = i + 1
a[0]
for item in a:
print(item)
执行结果:
[None, None, None, None, None, None, None, None, None, None]
1
2
3
4
5
6
7
8
9
10
数组操作 | Array类中的操作方法 |
---|---|
a = Array(10) | __init__(capacity, fileValue=None) |
len(a) | __len__() |
str(a) | __str__() |
for item in a: | __iter__() |
a[index] | __getitem__(index) |
a[index] = newItem | __setitem__(index, newItem) |
2.数组的操作
设置数组的初始大小为0,,容量为5
from lib.arrays import Array # lib目录自定义的Array类
DEFAULT_CAPACITY = 5
logicalSize = 0
a = Array(DEFAULT_CAPACITY)
print(a)
[None, None, None, None, None]
2.1增加数组的大小
- 创建一个新的,更大容量的数组
- 将旧的数组的数据,复制到新的数组中
- 将旧的数组变量重新设置为新的数组对象
if logicalSize == len(a):
temp = Array(len(a) + 1) # 创建一个新数组
for i in range(logicalSize): # 复制旧数组的数据到新数组
temp[i] = a[i]
a = temp # 重置旧数组的值到新数组
temp = Array(len(a) * 2)
print(temp)
[None, None, None, None, None, None, None, None, None, None]
2.2减小数组的大小
- 创建一个新的,更小的数组
- 将旧的数组的数据,复制到新的数组中
- 将旧的数组变量重新设置为新的数组对象
if logicalSize <= len(a) // 4 and len(a) >= DEFAULT_CAPACITY * 2:
temp = Array(len(a) // 2) # 创建一个新数组
for i in range(logicalSize): # 复制旧数组的数据到新数组
temp[i] = a[i]
a = temp # 重置旧数组的值到新数组
print(a)
[None, None, None, None, None]
2.3在数组中插入一项
- 在数组插入元素之前检查数组的物理大小(可用空间)
- 从数组的逻辑末尾开始,直到目标索引位置,将每一项都向后移动一个单元
- 将新的项赋值给目标索引位置
- 将逻辑大小增加1
from lib.arrays import Array
DEFAULT_CAPACITY = 5
logicalSize = 5
a = Array(DEFAULT_CAPACITY)
lst = ['D1', 'D2', 'D3', 'D4', 'D5']
for i in range(len(lst)):
a[i] = lst[i]
if logicalSize == len(a):
temp = Array(len(a) + 1) # 创建一个新数组,数组中增加物理大小
for i in range(logicalSize): # 复制旧数组的数据到新数组
temp[i] = a[i]
a = temp # 重置旧数组的值到新数组
targetIndex = 1
newItem = 'abc'
for i in range(logicalSize, targetIndex, -1):
a[i] = a[i-1] # 将项目向下移动一个位置
a[targetIndex] = newItem # 添加新项目并增加逻辑大小
print(a)
['D1', 'abc', 'D2', 'D3', 'D4', 'D5']
2.4从数组中删除一项
- 从紧跟目标索引位置之后的位置开始,到数组的逻辑末尾,将每一项都向前移动一位
- 将逻辑大小减1
- 检查浪费的空间,如果有必要,将数组的物理大小减一
from lib.arrays import Array
logicalSize = 6
targetIndex = 1
a = Array(logicalSize)
lst = ['D1', 'abc', 'D2', 'D3', 'D4', 'D5']
for i in range(len(lst)):
a[i] = lst[i]
for i in range(targetIndex, logicalSize-1):
a[i] = a[i+1]
if logicalSize == len(a):
temp = Array(len(a) - 1) # 创建一个新数组,数组中减少物理大小
logicalSize -= 1
for i in range(logicalSize): # 复制旧数组的数据到新数组
temp[i] = a[i]
a = temp # 重置旧数组的值到新数组
print(a)
['D1', 'D2', 'D3', 'D4', 'D5']
2.5 复杂度权衡:时间,空间和数组
数组操作 | 复杂度 |
---|---|
从第i个位置访问 | O(1),最好情况和最坏情况 |
在第i个位置替换 | O(1),最好情况和最坏情况 |
从逻辑末尾插入 | O(1),平均情况 |
从逻辑末尾删除 | O(1),平均情况 |
在第i个位置插入 | O(n),平均情况 |
从第i个位置删除 | O(n),平均情况 |
增加容量 | O(n),最好情况和最坏情况 |
减小容量 | O(n),最好情况和最坏情况 |
3.二维数组
创建二维数组的类
from lib.arrays import Array
class Grid(object):
"""二维数组"""
def __init__(self, rows, columns, fillValue=None):
self._data = Array(rows)
for row in range(rows):
self._data[row] = Array(columns, fillValue)
def getHeight(self):
"""返回行数"""
return len(self._data)
def getWidth(self):
"""返回列数"""
return len(self._data[0])
def __getitem__(self, index):
"""支持二维索引"""
return self._data[index]
def __str__(self):
"""返回网格的字符串表示形式"""
result = ""
for row in range(self.getHeight()):
for col in range(self.getWidth()):
result += str(self._data[row][col]) + " "
result += "\n"
return result
二维数组创建
#
from lib.grid import Grid
table = Grid(4, 5, 0)
print(table)
for j in range(4):
for i in range(5):
table[j][i] = i
print(table)
#二维数组初始化数据
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
#二维数组的使用
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4