算法入门
解决一个问题有不同的方法,一般来说所需步骤越少效果越好。但有时可能更在意其他方面,比如内存使用,而不是仅关注运行快慢。
算法来自波斯的一位博识者阿尔·花拉子米(Al-Khwarizmi),他在 9 世纪写了一本书,介绍了解方程的方法。
选择排序 selection sort
排序是日常最常见的算法场景之一,例如找最便宜的机票,按最新时间对邮件进行排序等。
选择排序是其中一种比较容易想到的方法,它的思路是找到最小的元素,将其放在第一位,然后找到第二小的元素,放在第二位,以此类推。
def selectionSort(arr):
newArr = []
for i in range(len(arr)):
smallest = findSmallest(arr)
newArr.append(arr.pop(smallest))
return newArr
def findSmallest(arr):
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
大 O 表示法 Big O Notation
为了比对算法的复杂度,发明了大 O 表示法,例如上面的选择排序,每个元素都需要比较,每次比较需要遍历后续所有元素,整体上需要接近 n*n 的计算步骤,所以复杂度是 O(n^2)。
归并排序 merge sort
归并排序提供了另外一种思路,将要排序的数组分成两个部分,分别排序,然后将排序好的两个数组合并。
def mergeSort(arr):
if len(arr) < 2:
return arr
mid = len(arr) // 2
left = arr[:mid]
right = arr[mid:]
return merge(mergeSort(left), mergeSort(right))
def merge(left, right):
result = []
while len(left) > 0 and len(right) > 0:
if left[0] < right[0]:
result.append(left.pop(0))
else:
result.append(right.pop(0))
result.extend(left)
result.extend(right)
return result
此时算法的复杂度下降到了 O(nlogn)。
Dijkstra 算法
Dijkstra 算法用于计算加权图中的最短路径,例如地图中的最短路线。从成本最低的点开始,计算到其他各点的最短路径,然后再计算剩下的点,以此类推。算法复杂度是 O(n^2)。