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中使用mechanize模块模拟浏览器功能
May 05 Python
利用python模拟实现POST请求提交图片的方法
Jul 25 Python
利用numpy实现一、二维数组的拼接简单代码示例
Dec 15 Python
Python求出0~100以内的所有素数
Jan 23 Python
代码讲解Python对Windows服务进行监控
Feb 11 Python
Python实现获取系统临时目录及临时文件的方法示例
Jun 26 Python
pycharm创建scrapy项目教程及遇到的坑解析
Aug 15 Python
python多任务之协程的使用详解
Aug 26 Python
pip install python 快速安装模块的教程图解
Oct 08 Python
NumPy中的维度Axis详解
Nov 26 Python
python进行OpenCV实战之画图(直线、矩形、圆形)
Aug 27 Python
Python+OpenCV实现在图像上绘制矩形
Mar 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表单提交问题的解决方法
2011/04/12 PHP
PHP获取搜索引擎关键字来源的函数(支持百度和谷歌等搜索引擎)
2012/10/03 PHP
destoon实现商铺管理主页设置增加新菜单的方法
2014/06/26 PHP
ThinkPHP控制器详解
2015/07/27 PHP
详解PHP中的状态模式编程
2015/08/11 PHP
ZendFramework2连接数据库操作实例
2017/04/18 PHP
javascript 有趣而诡异的数组
2009/04/06 Javascript
浅谈javascript的数据类型检测
2010/07/10 Javascript
深入理解JavaScript中的传值与传引用
2013/12/09 Javascript
《JavaScript DOM 编程艺术》读书笔记之DOM基础
2015/01/09 Javascript
JS数组的常见用法实例
2015/02/10 Javascript
js给网页加上背景音乐及选择音效的方法
2015/03/03 Javascript
Javascript实现图片懒加载插件的方法
2016/10/20 Javascript
BootStrap中
2016/12/10 Javascript
Bootstrap实现圆角、圆形头像和响应式图片
2016/12/14 Javascript
深究AngularJS中ng-drag、ng-drop的用法
2017/06/12 Javascript
jQuery模拟爆炸倒计时功能实例代码
2017/08/21 jQuery
详解Node全局变量global模块
2017/09/28 Javascript
ES6 迭代器(Iterator)和 for.of循环使用方法学习(总结)
2018/02/08 Javascript
vue+vant实现商品列表批量倒计时功能
2020/01/13 Javascript
es6 super关键字的理解与应用实例分析
2020/02/15 Javascript
[48:32]2018DOTA2亚洲邀请赛 3.31 小组赛 A组 LGD vs VG
2018/04/01 DOTA
Python数据分析之如何利用pandas查询数据示例代码
2017/09/01 Python
Python获取二维矩阵每列最大值的方法
2018/04/03 Python
在python中将字符串转为json对象并取值的方法
2018/12/31 Python
使用 Python 玩转 GitHub 的贡献板(推荐)
2019/04/04 Python
Flask框架搭建虚拟环境的步骤分析
2019/12/21 Python
python3 使用openpyxl将mysql数据写入xlsx的操作
2020/05/15 Python
Superdry瑞典官网:英国日本街头风品牌
2017/05/17 全球购物
idealfit英国:世界领先的女性健身用品和运动衣物品牌
2017/11/25 全球购物
研发工程师的岗位职责
2013/11/18 职场文书
办加油卡单位介绍信
2014/01/09 职场文书
创建省级文明单位实施方案
2014/02/27 职场文书
经理助理岗位职责
2015/02/02 职场文书
Python图片验证码降噪和8邻域降噪
2021/08/30 Python
netty 实现tomcat的示例代码
2022/06/05 Servers