一、概述

快速排序(quick sort)是一种分治排序算法。该算法首先 选取 一个划分元素(partition element,有时又称为pivot);接着重排列表将其 划分 为三个部分:left(小于划分元素pivot的部分)、划分元素pivot、right(大于划分元素pivot的部分),此时,划分元素pivot已经在列表的最终位置上;然后分别对left和right两个部分进行 递归排序。

其中,划分元素的 选取 直接影响到快速排序算法的效率,通常选择列表的第一个元素或者中间元素或者最后一个元素作为划分元素,当然也有更复杂的选择方式;划分 过程根据划分元素重排列表,是快速排序算法的关键所在,该过程的原理示意图如下:

<-- 选取划分元素 -->

<-- 划分过程 -->

<-- 划分结果 -->

快速排序算法的优点是:原位排序(只使用很小的辅助栈),平均情况下的时间复杂度为 O(n log n)。快速排序算法的缺点是:它是不稳定的排序算法,最坏情况下的时间复杂度为 O(n2)。

二、Python实现

1、标准实现

#!/usr/bin/env python
# -*- coding: utf-8 -*-
def stdQuicksort(L):
qsort(L, 0, len(L) - 1)
def qsort(L, first, last):
if first < last:
split = partition(L, first, last)
qsort(L, first, split - 1)
qsort(L, split + 1, last)
def partition(L, first, last):
# 选取列表中的第一个元素作为划分元素
pivot = L[first]
leftmark = first + 1
rightmark = last
while True:
while L[leftmark] <= pivot:
# 如果列表中存在与划分元素pivot相等的元素,让它位于left部分
# 以下检测用于划分元素pivot是列表中的最大元素时,
#防止leftmark越界
if leftmark == rightmark:
break
leftmark += 1
while L[rightmark] > pivot:
# 这里不需要检测,划分元素pivot是列表中的最小元素时,
# rightmark会自动停在first处
rightmark -= 1
if leftmark < rightmark:
# 此时,leftmark处的元素大于pivot,
#而rightmark处的元素小于等于pivot,交换二者
L[leftmark], L[rightmark] = L[rightmark], L[leftmark]
else:
break
# 交换first处的划分元素与rightmark处的元素
L[first], L[rightmark] = L[rightmark], L[first]
# 返回划分元素pivot的最终位置
return rightmark

2、Pythonic实现

# -*- coding: utf-8 -*-
def pycQuicksort(L):
if len(L) <= 1: return L
return pycQuicksort([x for x in L if x < L[0]]) + \
[x for x in L if x == L[0]] + \
pycQuicksort([x for x in L if x > L[0]])

对比 标准实现 可以看出,Pythonic实现 更简洁、更直观、更酷。但需要指出的是,Pythonic实现 使用了Python中的 列表解析 (List Comprehension,也叫列表展开、列表推导),每一次 递归排序 都会产生新的列表,因此失去了快速排序算法本来的 原位排序 的优点。

三、算法测试

if __name__ == '__main__':
L = [54, 26, 93, 17, 77, 31, 44, 55, 20]
M = L[:]
print('before stdQuicksort: ' + str(L))
stdQuicksort(L)
print('after stdQuicksort: ' + str(L))
print('before pycQuicksort: ' + str(M))
print('after pycQuicksort: ' + str(pycQuicksort(M)))

运行结果:

$ python testquicksort.py
before stdQuicksort: [54, 26, 93, 17, 77, 31, 44, 55, 20]
after stdQuicksort: [17, 20, 26, 31, 44, 54, 55, 77, 93]
before pycQuicksort: [54, 26, 93, 17, 77, 31, 44, 55, 20]
after pycQuicksort: [17, 20, 26, 31, 44, 54, 55, 77, 93]

最新文章

  1. spider RPC插件化体系
  2. Spring+EhCache缓存实例
  3. JS对象深刻理解 - 1
  4. infer.net 入门2 用一个侦探故事来讲解,通俗易懂
  5. ORM系列之一:Dos.ORM
  6. hdu 4961 Boring Sum
  7. 在 CentOS 中编译安装 VIM 7.3
  8. JavaWeb学习总结(三十五)——使用JDBC处理Oracle大数据
  9. tpopela/vips_java
  10. Eclipse中导入第三方源码的问题和备用解决方案
  11. 在MyEclipse中运行tomcat报错 严重: Error starting static Resources
  12. 关于我的PP0.1聊天软件(客户端)
  13. zabbix监控Elasticsearch集群
  14. linux命令 uname -r 和 uname -a 的解释与演示
  15. windows版本的phantomjs-2.1.1-windows安装
  16. JAVA数据库连接池C3p0 以及阿里Druid提供的连接池
  17. MD5=======RBAC权限管理
  18. git 查看一个分支是否被合并过
  19. [Java学习] Java Object类
  20. python常见异常提示

热门文章

  1. 一键洞察全量SQL ,远离性能异常
  2. Python编程进阶,Python如何实现多进程?
  3. android开发之当设置textview多少字后以省略号显示。限制TextView的字数
  4. Idea使用方式——创建类模板
  5. Mono生命周期小实验
  6. 面试【JAVA基础】多线程
  7. vue-element-admin改造接入后台,搭建有来商城youlai-mall后台前端管理平台
  8. leetcode刷题-56合并区间
  9. MongoDB基础总结
  10. Promise核心实现