文章目录

  • 一、快速排序
  • 二、归并排序




一、快速排序

快速排序其实是属于交换排序,不占用额外的空间,但是由于以来与原始的排序决定交换次数,因此也是一个不稳定的排序。在最好的情况下是O(logn), 但是在最坏的情况下是O(n2)。
快排的步骤:

  1. 在数组中选一个基准数(通常为数组第一个);
  2. 将数组中小于基准数的数据移到基准数左边,大于基准数的移到右边;
  3. 对于基准数左、右两边的数组,不断重复以上两个过程,直到每个子集只有一个元素,即为全部有序。

假设如下的list: 3,5,7,1,4
首先设置基准值为3,则最终比3小的应该排在3的左边,比3大的应该排在3的右边。
设置一个指针i,该指针初始化指向index=1的位置,指向当前第一个大于基准值的数值,即为将来的分割点——该分割点的左边都是小于等于3的数值,该分割点的右边都是大于3的数值。

i = 1, 从index=1到最后开始依次比较

快速排序算法实现 python 快速排序 python3_排序算法


当前j指向的数值5,大于基准值,当前第一个大于基准值的值仍旧是5,所以i指针不移动,j遍历到下一个进行比较。

快速排序算法实现 python 快速排序 python3_排序算法_02


当前j指向的数值7,大于基准值,当前第一个大于基准值的值仍旧是5,所以i指针不移动,j遍历到下一个进行比较。

快速排序算法实现 python 快速排序 python3_指针_03


当前j指向的数值1,小于基准值,当前大于基准值的第一个值为5,index是i指向的位置。应该将1与5做交换,i向后移动一个继续指向当前大于基准值的第一个7,j遍历到下一个进行比较。

快速排序算法实现 python 快速排序 python3_排序算法_04


当前j指向的数值4,大于基准值,当前第一个大于基准值的值仍旧是7,所以i指针不移动,j遍历到下一个结束本次比较,将基准值与当前i指针指向的前一位做交换(当前i指针指向的是大于基准值的第一个数字,该数字之前应该是小于基准值的所有数值)。

快速排序算法实现 python 快速排序 python3_快速排序算法实现 python_05

将这次排序好的数组分成两部分:
1,3
7,5,4

在递归的调用排序

def partition(arr, low, high):
    piovt = arr[low]
    # 标志当前交换的位置
    i = low + 1

    for j in range(low+1, high):
        if arr[j] < piovt:
            arr[j], arr[i] = arr[i], arr[j]
            i += 1

    arr[i-1], arr[low] = arr[low], arr[i-1]
    return i

# 快速排序函数
def quickSort(arr, low, high):
    if low < high:
        pi = partition(arr, low, high)
        # print(pi, low, high)

        quickSort(arr, low, pi - 1)
        quickSort(arr, pi, high)


# 测试
a = [3,3,3,3,1]
quickSort(a, 0, len(a))
print(a)

二、归并排序

归并排序采用分治的思想,先分开,然后分而治之,在合并在一起。
拿到一个带排序的数组,不断的递归将这个数组分成左右两份,直到不可再分。然后将左右两份merge到一起。
然后将不可再分的元素进行递归排序,排序的时候需要注意,递归到后面左、右两个子数组分别都有多个元素,需要一次比较,每次填充进新数组的元素应该是左右两个子数组中最小的元素。

快速排序算法实现 python 快速排序 python3_快速排序_06

def merge_sort(arr):
    if not arr:
        return
    if len(arr) == 1:
        return arr
    left = merge_sort(arr[: (len(arr)//2)])
    right = merge_sort(arr[(len(arr) // 2):])
    return merge(left, right)


def merge(left, right):
    h, j, res = 0, 0, []
    while h < len(left) and j < len(right):
        if left[h] > right[j]:
            res.append(right[j])
            j += 1
        else:
            res.append(left[h])
            h += 1

    if h < len(left):
        for num in left[h:]:
            res.append(num)
    else:
        for num in right[j:]:
            res.append(num)
    return res