2.1.内存的工作原理
把计算机的内存看作一个个带有地址的抽屉,把需要存放的东西放进内存中。
将数据存储到内存时,请求计算机提供存储空间,计算机就会提供一个存储地址。
当需要存储多项数据时,有两种基本方式----数组和链表。
2.2.数组和链表
链表:链表中的元素可以存储在内存的任何地方。
链表的每个元素都存储了下一个元素的地址,从而使一系列随机的内存地址串在一起。
在链表中添加元素很容易,只需将其放入内存,并将其地址存储到前一个元素中。
链表的优势在于插入元素方便。
但链表的缺点在于,不能直接读取列表的任意元素,因为不知道元素的地址,必须从第一个元素开始访问依次到达你想访 问的元素。
数组:由于数组中元素在内存中都是相连的,所以数组新插入元素就重新分配存储空间,非常麻烦耗时,还会不成功。
数组的优势在于随机读取元素时,数组的效率很高,因为数组的地址都知道,可以迅速的找到数组的任何元素。
2.3.术语
数组元素带编号,编号从0开始而不是1.从0开始让基于数组的代码编写起来更容易。
元素的位置称为索引。例: a = [10, 20, 30, 40], 元素20位于索引1处,而不是说元素20的位置为1.
数组 | 链表 | |
读取 | O(1) | O(n) |
插入 | O(n) | O(1) |
O(n)=线性时间 O(1)=常量时间
练习:假设你要编写一个记账的应用程序。
你每天都将所有的支出记录下来,并在月底统计支出,算算当月花了多少钱。因此,你执行的插入操作很多,但读取操作很少。该使用数组还是链表呢?
链表;因为链表插入速度远高于数组,同时该程序读取操作很少,所以使用链表优于数组。
2.4.插入与删除
使用链表插入很简单,只要修改之前元素的指向地址。
而数组插入,必须将后面的元素都向后移动,如空间不足,可能还得将整个数组移到另一个地方。
因此,当需要在中间插入元素时,链表是最好的选择。
同样,删除元素链表也是更好的选择,只需修改前一个元素指向的地址即可。
数组则要将所有之后前移填空。删除总能成功,如果内存不够,插入可能失败。
实际情况中,数组用的很多,因为它支持随机访问。有两种访问方式:随机访问和顺序访问。
链表只能进行顺序访问,一个接着一个的访问元素。
2.5.选择排序。
选择排序是一种灵巧的算法,但其速度不是很快。算法需要的总时间是O(n x n), 即O(n2)
代码:
#-*- coding=utf-8 -*-
def findSmallest(arr): #函数是找到数组中最小的元素
smallest = arr[0] #用于存储最小的值,同时假定第一个元素是最小的
smallest_index = 0 #最小的值的索引,同时也假定最小值的索引是0
for i in range(1, len(arr)): #遍历数组中每一个元素,从第二个开始
if arr[i] < smallest: #如果第二个元素小于第一个元素
smallest = arr[i] #那么赋值给smallest
smallest_index = i #索引同样操作
return smallest_index #返回数组中最小值的索引
def selectionSort(arr): #选择排序函数
newArr = [] #一个列表用于保存
for i in range(len(arr)): #遍历每一个元素
smallest = findSmallest(arr) #用上面的函数找到最小值
newArr.append(arr.pop(smallest))
return newArr
print(selectionSort([5, 3 ,6, 2, 10]))