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实现将DOC文档转换为PDF的方法
Jul 25 Python
Go语言基于Socket编写服务器端与客户端通信的实例
Feb 19 Python
Python面向对象特殊成员
Apr 24 Python
Python实现Logger打印功能的方法详解
Sep 01 Python
python中import与from方法总结(推荐)
Mar 21 Python
pyqt5对用qt designer设计的窗体实现弹出子窗口的示例
Jun 19 Python
Python中typing模块与类型注解的使用方法
Aug 05 Python
Python利用 utf-8-sig 编码格式解决写入 csv 文件乱码问题
Feb 21 Python
在django中查询获取数据,get, filter,all(),values()操作
Aug 09 Python
基于python+selenium自动健康打卡的实现代码
Jan 13 Python
PyQt5 显示超清高分辨率图片的方法
Apr 11 Python
如何利用Python实现一个论文降重工具
Jul 09 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工厂模式的好处
2013/06/18 PHP
Yii框架获取当前controlle和action对应id的方法
2014/12/03 PHP
微信开发之网页授权获取用户信息(二)
2016/01/08 PHP
Zend Framework教程之视图组件Zend_View用法详解
2016/03/05 PHP
thinkPHP基于ajax实现的菜单与分页示例
2016/07/12 PHP
php获取文章内容第一张图片的方法示例
2017/07/03 PHP
PHP验证类的封装与使用方法详解
2019/01/10 PHP
Laravel 中使用简单的方法跟踪用户是否在线(推荐)
2019/10/30 PHP
php ActiveMQ的安装与使用方法图文教程
2020/02/23 PHP
关于JavaScript中var声明变量作用域的推断
2010/12/16 Javascript
javascript关于open.window子页面执行完成后刷新父页面的问题分析
2015/04/27 Javascript
基于javascript实现彩票随机数生成(简单版)
2020/04/17 Javascript
探索angularjs+requirejs全面实现按需加载的套路
2016/02/26 Javascript
基于BootStrap Metronic开发框架经验小结【五】Bootstrap File Input文件上传插件的用法详解
2016/05/12 Javascript
jquery轮播的实现方式 附完整实例
2016/07/28 Javascript
JS中页面与页面之间超链接跳转中文乱码问题的解决办法
2016/12/15 Javascript
用户管理的设计_jquery的ajax实现二级联动效果
2017/07/13 jQuery
js 判断一个数字是不是2的n次方幂的实例
2017/11/26 Javascript
尝试自己动手用react来写一个分页组件(小结)
2018/02/09 Javascript
vue嵌套路由与404重定向实现方法分析
2018/05/04 Javascript
node.js自动上传ftp的脚本分享
2018/06/16 Javascript
react native 文字轮播的实现示例
2018/07/27 Javascript
JavaScript函数的特性与应用实践深入详解
2018/12/30 Javascript
从理论角度讨论JavaScript闭包
2019/04/03 Javascript
Vue打包部署到Nginx时,css样式不生效的解决方式
2020/08/03 Javascript
python读取注册表中值的方法
2013/04/08 Python
python写日志封装类实例
2015/06/28 Python
python 把数据 json格式输出的实例代码
2016/10/31 Python
浅析Python中的赋值和深浅拷贝
2017/08/15 Python
[原创]教女朋友学Python3(二)简单的输入输出及内置函数查看
2017/11/30 Python
python 请求服务器的实现代码(http请求和https请求)
2018/05/25 Python
Python学习笔记之图片人脸检测识别实例教程
2019/03/06 Python
Python+OpenCV实现旋转文本校正方式
2020/01/09 Python
广告学专业自荐信范文
2014/02/24 职场文书
经济信息系毕业生自荐信
2014/06/02 职场文书
英语分层教学实施方案
2014/06/15 职场文书