在数组中添加新元素可能很麻烦,如果没有了空间。就得移到内存的其他地方,因此添加新元素的速度会很慢。
解决办法:预留座位。即便当前只有三个待办事项,也请计算机提供10个位置,以防需要添加的代办事项,这样只要代办事项不超过10个就无需转移,这是一个不错的权变措施。但是有如下两个缺点,额外请求的位置可能根本用不上,这样浪费内存;代办事项超过10个后还需转移。
需要随机读取元素时数组的效率很高,因为可以迅速找到数组中的任何元素。
②链表链表中的元素可储存在内存的任何地方,链表的每一个元素都储存了下一个元素的地址,从而使一系列随机的内存地址串在一起。
这犹如寻宝游戏:你前往第1个地址,那里有一张纸条写着下一个元素地址为123,因此你前往地址123那里又有一个纸条写着下一个元素的地址为847,以此类推在电表中添加元素很容易,只需要放入内存并将地址储存到前一个元素中。使用链表时根本不需要移动元素。只要有足够的内存空间,就能为链表分配内存。
链表的优势:
插入元素:使用链表时插入元素很简单,只需要修改它前面那个元素指向的地址,而使用数组时必须将其后面元素的地址都向后移。(如果没有足够的空间,可能还得将整个数组复制到其他地方,因此当需要在中间插入元素时,链表是更好的选择)
删除元素:如果你要删除元素呢列表也是更好的选择,因为只需要修改前一个元素指向的地址即可。(使用数组后删除元素之后,必须将后面的元素都向前移)
链表的劣势:在需要读取列表的最后一个元素时,你不能直接读取,因为你不知道他所处的地址——必须先访问元素。从元素1中获取2的地址,从元素2中获取元素3的地址…以此类推,直到访问到最后一个元素需要同时读取所有。
所以,需要读取所有元素时链表的效率很高,读取一个元素根据其中的地址再读取第二个元元素的地址…以此类推,但如果你需要跳跃链表的效率真的很低。在链表中。在链表中元素并非靠在一起的,你无法迅速计算出第5个元素的内存地址,而必须先访问第1个元素,以获得第2个元素的地址,再访问第2个元素,以获取第3个元素的地址,以此类推直到访问第5个元素。
顺序访问:从第1个元素开始逐个地读取元素列表,只能顺序访问要读取电表的第10个元素,得先读取前9个元素,并沿链接找到第10个元素。(链表)
随机访问:意味着可直接跳到第10个元素。(数组)
小结:
| 数组 | 链表 | |
|---|---|---|
| 读取 | O(1) | O(N) |
| 插入 | O(N) | O(1) |
| 删除 | O(N) | O(1) |
引例:
假设你的计算机储存了很多乐曲。对于每一个乐队,你都记录了其作品被播放的次数。
现在,你要将这个列表按播放次数从多到少的顺序排列,从而将你喜欢的乐队。排序的一种办法是遍历这个列表,找到作品播放次数最多的乐队,并将该乐队添加到一个新列表中。再次这样做,找出播放次数第二多的乐队。继续这样做,你将得到一个有序的列表。
要找出播放次数最多的乐队必须检查列表中的每一个元素,正如上述的内容,这时需要时间为O(n),因此对于这种时间为O(n)的操作,你需要执行N次。需要的总时间为O(n*n)即O(n^2)
注:选择排序是一种灵巧的算法,但速度不是很快。快速排序是一种更快的排序算法,将在后面介绍…
代码实现:
def findsmallest(arr):
smallest=arr[0]#储存最小的值
smallest_index=0#储存最小元素的索引
for i in range(1,len(arr)):
if arr[i]


