Python一行代码实现快速排序

上期文章排序算法——(2)Python实现十大经常使用排序算法为你们介绍了十大经常使用排序算法的前五种(冒泡、选择、插入、希尔、归并),由于快速排序的重要性,因此今天将单独为你们介绍一下快速排序!html

1、算法介绍

排序算法(Sorting algorithm)是计算机科学最古老、最基本的课题之一。要想成为合格的程序员,就必须理解和掌握各类排序算法。其中"快速排序"(Quicksort)使用得最普遍,速度也较快。它是图灵奖得主C. A. R. Hoare(托尼·霍尔)于1960时提出来的。
在这里插入图片描述python

2、算法原理

快排的实现方式多种多样,猪哥给你们写一种容易理解的:分治+迭代,只须要三步:程序员

  1. 在数列之中,选择一个元素做为"基准"(pivot),或者叫比较值。
  2. 数列中全部元素都和这个基准值进行比较,若是比基准值小就移到基准值的左边,若是比基准值大就移到基准值的右边
  3. 以基准值左右两边的子列做为新数列,不断重复第一步和第二步,直到全部子集只剩下一个元素为止。

举个例子,假设我如今有一个数列须要使用快排来排序:{3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48},咱们来看看使用快排的详细步骤:面试

  1. 选取中间的26做为基准值(基准值能够随便选)
  2. 数列从第一个元素3开始和基准值26进行比较,小于基准值,那么将它放入左边的分区中,第二个元素44比基准值26大,把它放入右边的分区中,依次类推就获得下图中的第二列。
  3. 而后依次对左右两个分区进行再分区,获得下图中的第三列,依次往下,直到最后只有一个元素
  4. 分解完成再一层一层返回,返回规则是:左边分区+基准值+右边分区

在这里插入图片描述

3、代码实现

quick_sort = lambda array: array if len(array) <= 1 else quick_sort([item for item in array[1:] if item <= array[0]]) + [array[0]] + quick_sort([item for item in array[1:] if item > array[0]])

是否是很简洁很秀,若是再有面试官让你手写一个快排,你就把这行写上去吧,面试官见了都要喊你秀儿,哈哈。算法

在你感叹python吊炸天的同时,你因该考虑到代码的可读性问题,lambda函数设计是为了代码的简洁性,可是滥用的话会致使可读性变得极差,并且如今pep8代码规范中也不建议使用lambda函数了,建议使用关键字def去定义一个函数,因此下面猪哥给你们写一段符合pythonic风格的快排代码数组

def quick_sort(arr):
    """快速排序"""
    if len(arr) < 2:
        return arr
    # 选取基准,随便选哪一个均可以,选中间的便于理解
    mid = arr[len(arr) // 2]
    # 定义基准值左右两个数列
    left, right = [], []
    # 从原始数组中移除基准值
    arr.remove(mid)
    for item in arr:
        # 大于基准值放右边
        if item >= mid:
            right.append(item)
        else:
            # 小于基准值放左边
            left.append(item)
    # 使用迭代进行比较
    return quick_sort(left) + [mid] + quick_sort(right)

4、算法分析

  1. 稳定性:快排是一种不稳定排序,好比基准值的先后都存在与基准值相同的元素,那么相同值就会被放在一边,这样就打乱了以前的相对顺序
  2. 比较性:由于排序时元素之间须要比较,因此是比较排序
  3. 时间复杂度:快排的时间复杂度为O(nlogn)
  4. 空间复杂度:排序时须要另外申请空间,而且随着数列规模增大而增大,其复杂度为:O(nlogn)
  5. 归并排序与快排 :归并排序与快排两种排序思想都是分而治之,可是它们分解和合并的策略不同:归并是从中间直接将数列分红两个,而快排是比较后将小的放左边大的放右边,因此在合并的时候归并排序仍是须要将两个数列从新再次排序,而快排则是直接合并再也不须要排序,因此快排比归并排序更高效一些,能够从示意图中比较两者之间的区别。
    在这里插入图片描述

5、快排优化

快速排序有一个缺点就是对于小规模的数据集性能不是很好。可能有人认为能够忽略这个缺点不计,由于大多数排序都只要考虑大规模的适应性就好了。可是快速排序算法使用了分治技术,最终来讲大的数据集都要分为小的数据集来进行处理,因此快排分解到最后几层性能不是很好,因此咱们就可使用扬长避短的策略去优化快排:app

  1. 先使用快排对数据集进行排序,此时的数据集已经达到了基本有序的状态
  2. 而后当分区的规模达到必定小时,便中止快速排序算法,而是改用插入排序,由于咱们以前讲过插入排序在对基本有序的数据集排序有着接近线性的复杂度,性能比较好。

这一改进被证实比持续使用快速排序算法要有效的多。函数

6、模拟面试

  • 面试官:你了解快排吗?
  • 你:略知一二
  • 面试官:那你讲讲快排的算法思想吧
  • 你:快排基本思想是:从数据集中选取一个基准,而后让数据集的每一个元素和基准值比较,小于基准值的元素放入左边分区大于基准值的元素放入右边分区,最后以左右两边分区为新的数据集进行递归分区,直到只剩一个元素。
  • 面试官:快排有什么优势,有什么缺点?
  • 你:分治思想的排序在处理大数据集量时效果比较好,小数据集性能差些。
  • 面试官:那该如何优化?
  • 你:对大规模数据集进行快排,当分区的规模达到必定小时改用插入排序,插入排序在小数据规模时排序性能较好。
  • 面试官:那你能手写一个快排吗?
  • 你:
quick_sort = lambda array: array if len(array) <= 1 else quick_sort([item for item in array[1:] if item <= array[0]]) + [array[0]] + quick_sort([item for item in array[1:] if item > array[0]])

  

7、总结

快排是面试与考试中最高频的一种排序算法(没有之一),请你们务必理解与掌握,欢迎你们在评论区留言,同时也但愿你们转发分享让更多的人爱上python这门语言。性能

相关文章
相关标签/搜索