[DS+Algo] 006 两种简单排序及其代码实现

1. 快速排序 QuickSort

  • 又称划分交换排序(partition-exchange sort)
  • 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要
  • 然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行

1.1 步骤

  1. 从数列中挑出一个元素,称为"基准"(pivot)
  2. 排序数列,元素比基准值小的元素放到基准前面,所有比基准值大的元素放到基准后面
    • 相同的数两边都能放,统一就好
  3. 在这个分区结束之后,该基准就处于数列的中间位置(其实就是它最终的位置)
    • 这个称为分区(partition)操作
  4. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序
  5. 递归出口:数列的大小是零或一
    • 也就是已经被排序好了
    • 因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去

1.2 性能分析

  • 最优时间复杂度:O(nlogn)
  • 最坏时间复杂度:O(n2)
  • 稳定性:不稳定

1.3 Python 代码示例

  • 快排版本不唯一
  • 这个只能算是快排的思路,比较费空间
from random import randrange


def quick_sort(lst):
    n = len(lst)
    if n <= 1:
        return lst

    pivot = lst[-1]
    front, rear = [], []
    for i in range(n-1):
        if lst[i] < pivot:
            front.append(lst[i])
        else:
            rear.append(lst[i])
    return quick_sort(front) + [pivot] + quick_sort(rear)


if __name__ == "__main__":
    lst = [randrange(10, 100) for _ in range(10)]

    print(">>> before sort:", lst)
    new_list = quick_sort(lst)
    print(">>> after sort: ", new_list)
  • 改进后的快排
from random import randrange


def quick_sort(lst, start, stop):
    if stop <= start:
        return

    pivot = lst[stop]
    low, high = start, stop
    while low < high:
        while low < high and lst[low] < pivot:
            low += 1
        lst[high] = lst[low]
        while low < high and pivot <= lst[high]:
            high -= 1
        lst[low] = lst[high]
    lst[low] = pivot
    quick_sort(lst, start, low-1)
    quick_sort(lst, low+1, stop)


if __name__ == "__main__":
    lst = [randrange(10, 100) for _ in range(10)]

    print(">>> before sort:", lst)
    quick_sort(lst, 0, len(lst)-1)
    print(">>> after sort: ", lst)

2. 归并排序 MergeSort

2.1 步骤

  1. 先说出口:当数列中的元素小于等于 1 时,即可退出
  2. 将数列对半分开
  3. 左边递归地排序
  4. 右边递归地排序
  5. 将左右两边合并

2.2 性能分析

  • 最优时间复杂度:O(nlogn)
  • 最坏时间复杂度:O(nlogn)
  • 稳定性:稳定

2.3 Python 代码示例

from random import randrange


def merge_sort(lst):
    n = len(lst)
    if n <= 1:
        return lst

    mid = n // 2
    left = merge_sort(lst[:mid])
    right = merge_sort(lst[mid:])
    return merge(left, right)


def merge(left, right):
    L, R = 0, 0
    result = []
    nL, nR = len(left), len(right)
    while L < nL and R < nR:
        if left[L] < right[R]:
            result.append(left[L])
            L += 1
        else:
            result.append(right[R])
            R += 1
    if L < nL:
        result += left[L:]
    if R < nR:
        result += right[R:]
    return result


if __name__ == "__main__":
    lst = [randrange(10, 100) for _ in range(10)]

    print(">>> before sort:", lst)
    sorted_list = merge_sort(lst)
    print(">>> after sort: ", sorted_list)

猜你喜欢

转载自www.cnblogs.com/yorkyu/p/11979293.html
006