常见排序算法实现-图解(python版)

  • Post author:
  • Post category:python



常见的大O表示时间法的直观图。

冒泡排序:

这应该是最常见的排序,直接贴代码,原理在于每次循环都找到最大的值,放置于右边。时间复杂度为
O(n^{2})

n = 15
a = [10, 7, 11, 7, 18, 17, 9, 17, 0, 7, 3, 20, 20, 15, 9]

def bubble_sort(a:list):
    n = len(a)
    ac = a.copy()
    swap_size = 1
    while swap_size > 0:
        swap_size = 0
        for i in range(n-1):
            if ac[i] > ac[i+1]:
                ac[i],ac[i+1] = ac[i+1],ac[i]
                swap_size += 1
        n-=1
    return ac
ac=bubble_sort(a)
print(ac)

快速排序

快速排序属于D&C(divide and conquer)算法中的一种,是一种分而治之的思想,D&C的思想在于两点:

1. 找出简单的基线条件(base case);

2.如何缩小问题的规模,然后使其满足基线条件;

先考虑最简单的情况,什么数组不需要排序,当数组为空或者数组只有一个数的时候,不需要排序,也就是数组的长度是小于2时候,不需要排序,这个就是基线条件。

再来如果数组包含3个呢:

[30,15,10]

从数组选择一个元素,假设是第一个数,这个元素就是基准值pivot,接下来找比这个pivot大的数放后面,小的数放前面,这个也被成为分区(partitioning)得到三个数组:

[15,10],[30],[]

1.一个由所有小于基准值的数字组成的子数组;

2.基准值;

3.一个由所有大于基准值的数组组成的子数组;

现在左边子数组是无序的,需要进一步排序[15,10],如果左边也是无序的,那么也需要接着排序,根据递归的思想,可以写出这样:

quicksort([15, 10,33])
            |
quicksort([15, 10]) + [33] + quicksort([])

刚开始函数是原始数组,找到基准值,以及两边子数组,接着递归调用quicksort, 直到达到基准条件,那么就可以写出快速排序的代码了,如下:

def quicksort(array):
  if len(array) < 2:
    return array  #←------基线条件:为空或只包含一个元素的数组是“有序”的
  else:
    pivot = array[0]  #←------递归条件
    less = [i for i in array[1:] if i <= pivot]  #←------由所有小于等于基准值的元素组成的子数组

    greater = [i for i in array[1:] if i > pivot]  #←------由所有大于基准值的元素组成的子数组

    return quicksort(less) + [pivot] + quicksort(greater)

print(quicksort([10, 5, 2, 3]))

对于时间的复杂度,贴上书的图,例如1~8数字已经排序,最坏的情况就是类似这样,栈长为n,每次涉及到的元素从7,6…1,可以表示为1…n-1,所以是
O(n^{2})
,

那么最好的情况类似这样,

每一层的时间为
O(n^{2})
, 那么总时间复杂度就是
O(nlogn)

未完待续



版权声明:本文为u012895183原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。