CrashCourseComputerScience13算法入门

68 阅读2分钟

算法入门

解决一个问题有不同的方法,一般来说所需步骤越少效果越好。但有时可能更在意其他方面,比如内存使用,而不是仅关注运行快慢。
算法来自波斯的一位博识者阿尔·花拉子米(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)。