数组

  • 下标索引从0 开始
  • 存储的内存是连续的
  • 常见的操作是增删查改
  • 数组不能够越界(写程序的时候要注意边界条件)
  • 数组读取元素和更新元素的时间复杂度都是 O(1)
  • 插入数组存在三种操作
    • 尾部插入
    • 中间插入
    • 超范围插入(创建的新数组是原数组长度的两倍)
  • 删除操作
  • 数组的插入和删除操作的时间复杂度都是 O(n)
  • 数据的适用场景:读操作多,写操作少

链表

  • 链表(Linked list)是一种在物理上非连续、非顺序的数据结构,由若干个节点(node)组成
  • 有单向链表和双向链表
  • 单向链表的每个节点包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针 next
  • 链表的第一个节点被称作头节点,最后一个节点被称作尾节点,尾节点的 next 指针指向空(Null)
  • 链表在内存的存储方式是随机存储,可以灵活有效利用零散的碎片空间
  • 链表的基本操作:增删查改
  • 查找链表节点的时间复杂度是 O(n)
  • 插入节点
    • 尾部插入
    • 头部插入
    • 中间插入
  • 删除节点
    • 尾部插入
    • 头部插入
    • 中间插入
  • 插入和删除节点的时间复杂度是 O(1)
  • 链表的适用场景:需要在尾部频繁的插入、删除元素
查找 更新 插入 删除
数组 O(1) O(1) O(n) O(n)
链表 O(n) O(n) O(1) O(1)

代码演示

数组程序 1

  1. class MyArray:
  2. """
  3. 通过 python 的列表封装成数组
  4. 数组是没有负下标索引的
  5. """
  6. def __init__(self, capacity: int):
  7. self._data = []
  8. self._capacity = capacity
  9. def __getitem__(self, position: int) -> object:
  10. return self._data[position]
  11. def __setitem__(self, index: int, value: object):
  12. self._data[index] = value
  13. def __len__(self) -> int:
  14. return len(self._data)
  15. def __iter__(self):
  16. for item in self._data:
  17. yield item
  18. def find(self, index: int) -> object:
  19. try:
  20. return self._data[index]
  21. except IndexError:
  22. return None
  23. def delete(self, index: int) -> bool:
  24. try:
  25. self._data.pop(index)
  26. return True
  27. except IndexError:
  28. return False
  29. def insert(self, index: int, value: int) -> bool:
  30. if len(self) >= self._capacity:
  31. return False
  32. else:
  33. return self._data.insert(index, value)
  34. def print_all(self):
  35. for item in self:
  36. print(item)
  37. def test_myarray():
  38. array = MyArray(5)
  39. array.insert(0, 3)
  40. array.insert(0, 4)
  41. array.insert(1, 5)
  42. array.insert(3, 9)
  43. array.insert(3, 10)
  44. assert array.insert(0, 100) is False # 插满以后不能再插入
  45. assert len(array) == 5
  46. assert array.find(1) == 5
  47. assert array.delete(4) is True
  48. print("array.find(6)", array.find(6)) # 索引超出范围
  49. array.print_all()
  50. if __name__ == "__main__":
  51. test_myarray()

数组程序 2

  1. class MyArray:
  2. """
  3. 通过 python 的列表封装成数组
  4. 数组是没有负下标索引的
  5. """
  6. def __init__(self, capacity: int):
  7. self._data = []
  8. self._capacity = capacity
  9. def __getitem__(self, position: int) -> object:
  10. return self._data[position]
  11. def __setitem__(self, index: int, value: object):
  12. self._data[index] = value
  13. def __len__(self) -> int:
  14. return len(self._data)
  15. def __iter__(self):
  16. for item in self._data:
  17. yield item
  18. def find(self, index: int) -> object:
  19. try:
  20. return self._data[index]
  21. except IndexError:
  22. return None
  23. def delete(self, index: int) -> bool:
  24. try:
  25. self._data.pop(index)
  26. return True
  27. except IndexError:
  28. return False
  29. # 可以超范围插入
  30. def insert(self, index: int, value: int) -> bool:
  31. if len(self) >= self._capacity:
  32. self._capacity = 2*self._capacity # 扩容两倍
  33. return self._data.insert(index, value)
  34. else:
  35. return self._data.insert(index, value)
  36. def print_all(self):
  37. for item in self:
  38. print(item)
  39. def test_myarray():
  40. array = MyArray(5)
  41. array.insert(0, 3)
  42. array.insert(0, 4)
  43. array.insert(1, 5)
  44. array.insert(3, 9)
  45. array.insert(3, 10)
  46. for i in range(6):
  47. array.insert(i, i)
  48. print("len(array)", len(array)) # 这样跟定义的数组长度冲突,容易引发歧义,不建议使用
  49. array.print_all()
  50. if __name__ == "__main__":
  51. test_myarray()