Python实现的数据结构与算法之快速排序详解


Posted in Python onApril 22, 2015

本文实例讲述了Python实现的数据结构与算法之快速排序。分享给大家供大家参考。具体分析如下:

一、概述

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

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

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

Python实现的数据结构与算法之快速排序详解

<-- 划分过程 -->

Python实现的数据结构与算法之快速排序详解

<-- 划分结果 -->

Python实现的数据结构与算法之快速排序详解

快速排序算法的优点是:原位排序(只使用很小的辅助栈),平均情况下的时间复杂度为 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实现

#!/usr/bin/env python
# -*- 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,也叫列表展开、列表推导),每一次 递归排序 都会产生新的列表,因此失去了快速排序算法本来的 原位排序 的优点。

三、算法测试

#!/usr/bin/env python
# -*- coding: utf-8 -*-
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]

希望本文所述对大家的Python程序设计有所帮助。

Python 相关文章推荐
在Python中使用swapCase()方法转换大小写的教程
May 20 Python
Python实现中文数字转换为阿拉伯数字的方法示例
May 26 Python
Python3 加密(hashlib和hmac)模块的实现
Nov 23 Python
详解Python3 中hasattr()、getattr()、setattr()、delattr()函数及示例代码数
Apr 18 Python
Python实现读写INI配置文件的方法示例
Jun 09 Python
对IPython交互模式下的退出方法详解
Feb 16 Python
使用matplotlib中scatter方法画散点图
Mar 19 Python
Python实现12306火车票抢票系统
Jul 04 Python
python networkx 根据图的权重画图实现
Jul 10 Python
Python创建一个元素都为0的列表实例
Nov 28 Python
python-docx文件定位读取过程(尝试替换)
Feb 13 Python
logging level级别介绍
Feb 21 Python
利用Fn.py库在Python中进行函数式编程
Apr 22 #Python
Python实现的数据结构与算法之基本搜索详解
Apr 22 #Python
Python实现的数据结构与算法之链表详解
Apr 22 #Python
Python实现的数据结构与算法之双端队列详解
Apr 22 #Python
Python实现的数据结构与算法之队列详解
Apr 22 #Python
详尽讲述用Python的Django框架测试驱动开发的教程
Apr 22 #Python
Hadoop中的Python框架的使用指南
Apr 22 #Python
You might like
php+mysql实现用户注册登陆的方法
2015/01/03 PHP
基于PHP实现的事件机制实例分析
2015/06/18 PHP
THINKPHP3.2使用soap连接webservice的解决方法
2017/12/13 PHP
Lumen timezone 时区设置方法(慢了8个小时)
2018/01/20 PHP
Laravel Eloquent ORM 实现查询表中指定的字段
2019/10/17 PHP
PHP如何使用JWT做Api接口身份认证的实现
2020/02/03 PHP
关于 byval 与 byref 的区别分析总结
2007/10/08 Javascript
JavaScript快速检测浏览器对CSS3特性的支持情况
2012/09/26 Javascript
删除Javascript Object中间的key
2014/11/18 Javascript
实例详解JavaScript获取链接参数的方法
2016/01/01 Javascript
JS随机洗牌算法之数组随机排序
2016/03/23 Javascript
jQuery使用EasyUi实现三级联动下拉框效果
2017/03/08 Javascript
JavaScript学习总结之正则的元字符和一些简单的应用
2017/06/30 Javascript
BootStrap入门学习第一篇
2017/08/28 Javascript
NodeJs实现定时任务的示例代码
2017/12/05 NodeJs
AngularJS实现的生成随机数与猜数字大小功能示例
2017/12/25 Javascript
webpack4.0+vue2.0利用批处理生成前端单页或多页应用的方法
2019/06/28 Javascript
基于js实现判断浏览器类型代码实例
2020/07/17 Javascript
vue-cli3自动消除console.log()的调试信息方式
2020/10/21 Javascript
原生js实现弹窗消息动画
2020/11/20 Javascript
使用python实现生成用户信息
2017/03/20 Python
linux环境下的python安装过程图解(含setuptools)
2017/11/22 Python
Python实现读取Properties配置文件的方法
2018/03/29 Python
基于PyQt4和PySide实现输入对话框效果
2019/02/27 Python
pandas如何处理缺失值
2019/07/31 Python
Python创建数字列表的示例
2019/11/28 Python
使用HTML5里的classList操作CSS类
2016/06/28 HTML / CSS
皇家阿尔伯特英国官方商店:Royal Albert骨瓷
2019/03/25 全球购物
如何安装ruby on rails
2014/02/09 面试题
社区庆八一活动方案
2014/02/02 职场文书
副职竞争上岗演讲稿
2014/05/12 职场文书
工作所在部门证明
2014/09/21 职场文书
后勤工作个人总结
2015/02/28 职场文书
锦旗赠语
2015/06/23 职场文书
MySQL中InnoDB存储引擎的锁的基本使用教程
2021/05/26 MySQL
python利用pandas分析学生期末成绩实例代码
2021/07/09 Python