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类继承用法实例分析
Oct 10 Python
在Python的Django框架中显示对象子集的方法
Jul 21 Python
Python学习笔记之解析json的方法分析
Apr 21 Python
Python将多个list合并为1个list的方法
Jun 27 Python
对python中的乘法dot和对应分量相乘multiply详解
Nov 14 Python
python flask解析json数据不完整的解决方法
May 26 Python
微信小程序python用户认证的实现
Jul 29 Python
基于Python实现拆分和合并GIF动态图
Oct 22 Python
Ubuntu下Python+Flask分分钟搭建自己的服务器教程
Nov 19 Python
用Python去除图像的黑色或白色背景实例
Dec 12 Python
Python文本处理简单易懂方法解析
Dec 19 Python
Python3自动生成MySQL数据字典的markdown文本的实现
May 07 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&amp;java(二)
2006/10/09 PHP
php开发工具之vs2005图解
2008/01/12 PHP
ThinkPHP中的三大自动简介
2014/08/22 PHP
PHP CodeIgniter框架的工作原理研究
2015/03/30 PHP
php简单防盗链实现方法
2015/07/29 PHP
ThinkPHP框架使用redirect实现页面重定向的方法实例分析
2018/04/12 PHP
jQuery表格插件ParamQuery简单使用方法示例
2013/12/05 Javascript
JS动态调用方法名示例介绍
2013/12/18 Javascript
JS替换字符串中字符即替换全部而不是第一个
2014/06/04 Javascript
JavaScript中的style.cssText使用教程
2014/11/06 Javascript
借助FileReader实现将文件编码为Base64后通过AJAX上传
2015/12/24 Javascript
JavaScript中通过提示框跳转页面的方法
2016/02/14 Javascript
jQuery和CSS仿京东仿淘宝列表导航菜单
2017/01/04 Javascript
Vue框架中正确引入JS库的方法介绍
2017/07/30 Javascript
探秘vue-rx 2.0(推荐)
2018/09/21 Javascript
基于iview-admin实现动态路由的示例代码
2019/10/02 Javascript
javascript实现滚动条效果
2020/03/24 Javascript
vue中解决微信html5原生ios虚拟键返回不刷新问题
2020/10/20 Javascript
[04:44]DOTA2 2017全国高校联赛视频回顾
2017/08/21 DOTA
python的即时标记项目练习笔记
2014/09/18 Python
hmac模块生成加入了密钥的消息摘要详解
2018/01/11 Python
python脚本生成caffe train_list.txt的方法
2018/04/27 Python
PyTorch CNN实战之MNIST手写数字识别示例
2018/05/29 Python
Python tkinter label 更新方法
2018/10/11 Python
python脚本当作Linux中的服务启动实现方法
2019/06/28 Python
解决Djang2.0.1中的reverse导入失败的问题
2019/08/16 Python
详解基于Jupyter notebooks采用sklearn库实现多元回归方程编程
2020/03/25 Python
python thrift 实现 单端口多服务的过程
2020/06/08 Python
化学专业毕业生自荐信
2013/11/15 职场文书
机关领导干部作风整顿整改措施
2014/09/19 职场文书
商务宴请邀请函范文
2015/02/02 职场文书
高三物理教学反思
2016/02/20 职场文书
Java实战之用Swing实现通讯录管理系统
2021/06/13 Java/Android
React 并发功能体验(前端的并发模式)
2021/07/01 Javascript
SpringBoot2零基础到精通之数据库专项精讲
2022/03/22 Java/Android
pycharm安装深度学习pytorch的d2l包失败问题解决
2022/03/25 Python