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创建XML文档
Mar 01 Python
Python 多核并行计算的示例代码
Nov 07 Python
利用Python进行异常值分析实例代码
Dec 07 Python
python中多个装饰器的执行顺序详解
Oct 08 Python
IntelliJ IDEA安装运行python插件方法
Dec 10 Python
Python判断是否json是否包含一个key的方法
Dec 31 Python
Python制作动态字符图的实例
Jan 27 Python
django项目环境搭建及在虚拟机本地创建django项目的教程
Aug 02 Python
Python Web框架之Django框架cookie和session用法分析
Aug 16 Python
python 爬取疫情数据的源码
Feb 09 Python
python日期与时间戳的各种转换示例
Feb 12 Python
如何用python写个模板引擎
Jan 14 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
漫威DC御用漫画家去世 他的表情包曾走红网络
2020/04/09 欧美动漫
用PHP连接Oracle for NT 远程数据库
2006/10/09 PHP
Yii2超好用的日期和时间组件(值得收藏)
2016/05/05 PHP
PHP join()函数用法与实例讲解
2019/03/11 PHP
PHP Web表单生成器案例分析
2020/06/02 PHP
js程序中美元符号$是什么
2008/06/05 Javascript
JavaScript的parseInt 进制问题
2009/05/07 Javascript
JavaScript对象创建及继承原理实例解剖
2013/02/28 Javascript
javascript实现给定半径求出圆的面积
2015/06/26 Javascript
学习JavaScript设计模式之中介者模式
2016/01/14 Javascript
js+html5实现canvas绘制椭圆形图案的方法
2016/05/21 Javascript
js获取元素下的第一级子元素的方法(推荐)
2017/03/05 Javascript
原生JS实现导航下拉菜单效果
2020/11/25 Javascript
详解通过JSON数据使用VUE.JS
2017/05/26 Javascript
jQuery选取所有复选框被选中的值并用Ajax异步提交数据的实例
2017/08/04 jQuery
JS实现的简单表单验证功能完整实例
2017/10/14 Javascript
[01:02:46]VGJ.S vs NB 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
简单的Python的curses库使用教程
2015/04/11 Python
Python使用turtule画五角星的方法
2015/07/09 Python
神经网络(BP)算法Python实现及应用
2018/04/16 Python
python数字图像处理之骨架提取与分水岭算法
2018/04/27 Python
Python使用paramiko操作linux的方法讲解
2019/02/25 Python
Python文件打开方式实例详解【a、a+、r+、w+区别】
2019/03/30 Python
Python如何使用paramiko模块连接linux
2020/03/18 Python
TensorFlow实现批量归一化操作的示例
2020/04/22 Python
在Python中字典按值排序的实现方法
2020/11/12 Python
Expedia泰国:预订机票、酒店和旅游包(航班+酒店)
2016/09/27 全球购物
LEGO玩具英国官方商店:LEGO Shop GB
2018/03/27 全球购物
英国在线泳装店:Simply Swim
2019/05/05 全球购物
Fnac西班牙官网:法国文化和电子产品零售商
2021/03/14 全球购物
某同学的自我鉴定范文
2013/12/26 职场文书
招股说明书范本
2014/05/06 职场文书
八项规定个人对照检查材料思想汇报
2014/09/25 职场文书
教师评职称工作总结2015
2015/04/20 职场文书
2019军训心得体会
2019/06/27 职场文书
使用Redis做预定库存缓存功能
2022/04/02 Redis