vlambda博客
学习文章列表

算法图解第二章—选择排序


内存的工作原理

数组

使用数组意味着计算机提供的存储空间是相连的
算法图解第二章—选择排序使用数组意味着所有待办事项在内存中都是相连的(紧靠在一起的)。现在假设你要添加第四个待办事项,但后面的那个抽屉放着别人的东西!
算法图解第二章—选择排序
在这种情况下,你需要请求计算机重新分配一块可容纳4个待办事项的内存,再将所有待办事项都移到那里。在数组中添加新元素也可能很麻烦。如果没有了空间,就得移到内存的其他地方,因此添加新元素的速度会很慢。一种解决之道是“预留座位”:即便当前只有3个待办事项,也请计算机提供10个位置,以防需要添加待办事项。这样,只要待办事项不超过10个,就无需转移。这是一个不错的权变措施,但它存在如下两个缺点。

  1. 你额外请求的位置可能根本用不上,这将浪费内存。你没有使用,别人也用不了。

  2. 待办事项超过10个后,你还得转移。

链表

术语

数组的元素带编号,编号从0而不是1开始。
算法图解第二章—选择排序

元素的位置称为索引 。因此,不说“元素20的位置为1”,而说“元素20位于索引1处”。

下面列出了常见的数组和链表操作的运行时间。

算法图解第二章—选择排序

在中间插入

删除

选择排序

假设我们需要将一个包含N个数的乱序数组从小到大排列,我们要怎么实现?我们可以首先找出这N个数中的最小值,将它放入一个新建的数组里,再在剩余N-1个数里找最小值,再添加在新建数组里索引为1处,以此类推。

第一次需要检查n 个元素,但随后检查的元素数依次为n - 1, n – 2, …, 2和1。平均每次检查的元素数为1/2 × n ,因此运行时间为O (n × 1/2 × n )。但大O表示法省略诸如1/2这样的常数(有关这方面的完整讨论,请参阅第4章),因此简单地写作O (n × n )或O (n^2 )。选择排序是一种灵巧的算法,但其速度不是很快。快速排序是一种更快的排序算法,其运行时间为O (n log n ),这将在下一章介绍。

python3代码实现:

'''选择排序'''
'''将一组乱序的数组从小到大排列'''
def findsmallest(arr):
''' find the index of the smallest value'''
smallest = arr[0]
smallest_index = 0
for i in range(1,len(arr)):
if arr[i] < smallest:
smallest = arr[i]
smallest_index = i
return smallest_index

def selectionsort(arr):
'''选择排序,建立一个新数组,将最小值依次放入'''
sortrd_array = []
for i in range(len(arr)):
smallest_index = findsmallest(arr)
sortrd_array.append(arr[smallest_index])
arr.pop(smallest_index)
return sortrd_array

test_array = [2,8,5,7,9,4]
print(selectionsort(test_array))