博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
快速排序(Python实现)
阅读量:4188 次
发布时间:2019-05-26

本文共 2331 字,大约阅读时间需要 7 分钟。

目录


快速排序思路

快速排序又称为分割交换排序法,是目前公认最佳的排序法,也是使用“分而治之"的方式,先会在数据中找到一个虚拟的中间值,并按此中间值将所有打算排序的数据分为两部分。其中小于中间值的数据放在一边,而大于中间值的数据放在另一边,再以同样的方式分别处理左右两边的数据,直到排序完成为止。

逻辑演示

以一串数据 72, 6, 57, 88, 60, 42,83, 73, 48, 85 为例进行快速排序,将数据按照数值由小到大的顺序排序。

排序前:

72 6 57 88 60 42 83 73 48 85

我们假设虚拟的中间值总位于未排序部分的最左端,因此,第一次划分的虚拟中间值x应该是72。即 x => 72。

我们将待排序数列的最左端下标变量为left = 0,最右端下标变量为right = length - 1 = 9。同时设置两个游标 i = left, j = right。

因此排序前的数列如下:

72 6 57 88 60 42 83 73 48 85
x, left, i right, j

Step1

我们将游标j缓慢的向左移动,找到一个小于虚拟中间值的数字。显然,当游标j移动到48时,此时48 < 72 = x,因此48就是我们要找的数。此时让游标 i 对应位置的数据值填入48。

48 6 57 88 60 42 83 73 48 85
left, i j right

( x = 72 )

填入数据后,i 向右移动一格。

48 6 57 88 60 42 83 73 48 85
left i j right

接下来我们将游标 i 缓慢的向右移动,找到一个大于虚拟中间值的数字。显然,当游标 i 移动到88时,此时88 > 72 = x,因此88就是我们要找的数。此时让游标 j 对应的位置的数据值填入88。

48 6 57 88 60 42 83 73 88 85
left i j right

( x = 72 )

填入数据后,j 向左移动一格。

48 6 57 88 60 42 83 73 88 85
left i j right

Step2

经过一轮移动后,并没有完全将虚拟中间值72把数列分开。因为此时两个游标并没有遍历完全部数据。

我们继续将游标 j 缓慢的向左移动,重复上面的规则,找到一个小于虚拟中间值的数字。显然,当游标 j 移动到42时,此时 42 < 72 = x,因此42就是我们要找的数。此时让游标 i 对应位置的数据值填入42。

48 6 57 42 60 42 83 73 88 85
left i j right

填入数据后,i 向右移动一格。

48 6 57 42 60 42 83 73 88 85
left i j right

我们继续将 i 缓慢向右移动,来寻找一个大于虚拟中间值的数字。当 i 再次向右移动的时候,我们发现此时 i 和 j 对应的下标重叠了。也就是说,i 左边的数字没有大于虚拟中间值的数字,而 j 右边的数字没有小于虚拟中间值的数字,此时 i 和 j 交汇的点就是本轮排序虚拟中间值所在的位置。将虚拟中间值填入该位置中:

48 6 57 42 60 72 83 73 88 85
left i, j right

至此,虚拟中间值72找到了它应该所在的位置上。我们使用重复的逻辑对72之前的数列 48, 6, 57, 42, 60 和 72之后的数列 83, 73, 88, 85 进行排序,最终得到排好序的数列。

代码

def quick_sort(array, left, right):    if left >= right:        return    i = left    j = right    x = array[i]    while True:        # 从j开始向前找一个小于或等于x的数        while j >= i:            if array[j] <= x:                break            j -= 1        if i >= j:            array[i] = x            break        array[i] = array[j]        i += 1        # 从i开始向后找一个大于x的数        while i < j:            if array[i] > x:                break            i += 1        if i >= j:            array[i] = x            break        array[j] = array[i]        j -= 1    quick_sort(array, left, i-1)    quick_sort(array, i+1, right)if __name__ == '__main__':    demo = [72, 6, 57, 88, 60, 42, 83, 73, 48, 85]    quick_sort(demo, 0, len(demo)-1)    print(demo)

复杂度分析

  • 在最快和平均情况下,时间复杂度为 O(nlog_{2}n) 。最坏情况就是每次挑中的虚拟中间值不是最大就是最小,因而最坏情况下的时间复杂度为 O(n^{2}) 。
  • 快速排序法不是稳定排序法。
  • 在最差情况下,空间复杂度为 O(n) , 而最佳情况为 O(log_{2}n)
  • 快速排序法是平均运行时间最快的排序法。

转载地址:http://kdsoi.baihongyu.com/

你可能感兴趣的文章
图解EasyJWeb框架结构
查看>>
插件开发招人及《开源人》征稿
查看>>
换电脑了
查看>>
写代码.VS.写作
查看>>
偶的blog百篇原创留念-呵呵
查看>>
《深入Spring2》终于开始发布电子版本了
查看>>
这样的开源基金设想行得通吗?
查看>>
从山丘锤王之死谈Spring AOP中的引介(Introduction)
查看>>
有谁知道10级的山丘之王是怎么死的?
查看>>
开始学习写日记
查看>>
中国开源众生相-也谈“中国人的开源”
查看>>
Velocity脚本简明教程推荐
查看>>
空(标识)接口的重要性
查看>>
用AspectJ做的一个回合格斗小游戏
查看>>
在EasyJWeb中使用Java Excel API 处理电子表格
查看>>
在Spring中使用replaced-method来进行方法替换
查看>>
开始全心投入《深入Spring 2:轻量级J2EE开发框架原理与实践》
查看>>
使用CGLIB轻松实现延迟加载(Lazyload)
查看>>
好日子里谈开源
查看>>
超轻量级开源ORM系统EasyDBO最后一个测试版(0.9.0)发布
查看>>