算法的概念
我们暂时不要求各位掌握任何算法,只需要先从概念上了解一下它们是什么就行。
比如,我们想写一个程序,把给定的一堆数字从大到小进行排序。当只有几个数字的时候,比如10, 3, 20, 17, 8
,我们觉得,一眼就能看出来答案是 20, 17, 10, 8, 3
,所以不需要什么流程。但是,当数字很多很多的时候,流程的重要性就体现出来了。只有遵照流程,有条不紊地进行,才不会在排序过程中出错。不信的话,试试排列以下数字。
8, 52, 86, 39, 34, 15, 96, 95, 79, 70, 72, 42, 48, 35, 58, 81, 42, 29, 56, 72, 90, 80, 53, 17, 87, 4, 0, 49, 46, 74, 27, 86, 6, 88, 30, 15, 52, 56, 39, 65, 36, 50, 54, 73, 85, 21, 5, 15, 38, 28, 99, 68, 74, 4, 35, 16, 68, 23, 19, 35, 53, 92, 78, 73, 34, 53, 98, 49, 10, 56, 94, 37, 36, 25, 45, 40, 48, 58, 57, 34, 99, 83, 30, 86, 14, 69, 20, 57, 19, 74, 40, 22, 76, 21, 79, 92, 25, 93, 60, 32。
那么,要根据怎么样的流程去做呢?你可能可以这样:把所有数字看一遍,把最大的拿出来;然后再看一遍剩下的数字,把最大的拿出来(这是第二大的)...如此反复,就把它重新排列好了。
用 python
写出来的话,是这样
def sort_numbers(numbers):
result = [] # 这里记录排列好的序列
while numbers: # 一直循环,直到 numbers 为空
curr_max = -float('inf') # 记录当前最大的数,因为还没开始,所以是负无穷大
curr_max_idx = 0 # 记录当前最大的数在第几个
for idx in range(len(numbers)):
if numbers[idx] > curr_max:
curr_max = numbers[idx]
curr_max_idx = idx
numbers.pop(curr_max_idx) # 把 numbers 里面最大的那个数扔掉
result.append(curr_max) # 把这个最大的数放到 result 数组里面
return result # 返回的 result 就是排列好的数组了
但是,这个程序的效率其实很差劲。对十万个随机数字 ([random.randint(0, 100000) for _ in range(100000)]
) 进行排序,花费的时间是 169.0475
秒,而使用 python
自带的 sort
函数,则只需要 0.0222
秒。
我们暂时不去想 python
的 sort
是怎么实现的(它一定使用了更聪明的办法)。我们只要知道,算法在效率上是分优劣的。在我们的 sort_numbers
中,我们不停地把数字看了一遍又一遍,这非常浪费时间,可能也不是很有必要,这是需要被优化的。