一、概述

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

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

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

<-- 划分过程 -->

<-- 划分结果 -->

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

  1. 用Python实现的数据结构与算法:开篇

    一.概述 用Python实现的数据结构与算法 涵盖了常用的数据结构与算法(全部由Python语言实现),是 Problem Solving with Algorithms and Data Struc ...

  2. Python实现的数据结构与算法之队列详解

    本文实例讲述了Python实现的数据结构与算法之队列.分享给大家供大家参考.具体分析如下: 一.概述 队列(Queue)是一种先进先出(FIFO)的线性数据结构,插入操作在队尾(rear)进行,删除操 ...

  3. 用python语言讲解数据结构与算法

    写在前面的话:关于数据结构与算法讲解的书籍很多,但是用python语言去实现的不是很多,最近有幸看到一本这样的书籍,由Brad Miller and David Ranum编写的<Problem ...

  4. python 下的数据结构与算法---8:哈希一下【dict与set的实现】

    少年,不知道你好记不记得第三篇文章讲python内建数据结构的方法及其时间复杂度时里面关于dict与set的时间复杂度[为何访问元素为O(1)]原理我说后面讲吗?其实就是这篇文章讲啦. 目录: 一:H ...

  5. python 下的数据结构与算法---1:让一切从无关开始

    这段时间把<Data Structure and Algorithms with python>以及<Problem Solving with  Algorithms and Dat ...

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

    一.概述 快速排序(quick sort)是一种分治排序算法.该算法首先 选取 一个划分元素(partition element,有时又称为pivot):接着重排列表将其 划分 为三个部分:left( ...

  7. python数据结构与算法——快速排序

    快速排序通过不断将数列分段,使得较小的数在左边的序列,较大的数在右边的序列,不断重复此过程实现排序效果.通过设置两个哨兵不断的找两个序列的较小数,较大数,并把左右的数据互换,实现对数据从粗到细的排序. ...

  8. 用Python实现的数据结构与算法:堆栈

    一.概述 堆栈(Stack)是一种后进先出(LIFO)的线性数据结构,对堆栈的插入和删除操作都只能在栈顶(top)进行. 二.ADT 堆栈ADT(抽象数据类型)一般提供以下接口: Stack() 创建 ...

  9. Python中的数据结构和算法

    一.算法 1.算法的时间复杂度 大 O 记法,是描述算法复杂度的符号O(1) 常数复杂度,最快速的算法. 取数组第 1000000 个元素 字典和集合的存取都是 O(1) 数组的存取是 O(1) O( ...

随机推荐

  1. eclipse检出SVN代码的详细流程

    1.添加SVN资源库位置(未安装SVN,请先安装SVN) 2.因为该项目不是maven项目 所以还需要加入jar包(将项目lib里面的jar都Buile Path) 3.我这个项目需要修改编码格式 右 ...

  2. linux-shell-screen后台调用-后台运行脚本和命令-仿start命令-伪窗口界面

    序 我比较熟练bat.cmd脚本.刚接触使用shell时,总会习惯想用windows窗口界面来套用shell脚本.于是找到screen后台命令,它可以交互shell脚本,保持后台运行.但是在批处理ba ...

  3. centos7.6 安装 openvpn--2.4.7

    openvpn-server端 搭建 1,软件版本 Centos - 7.x easy-rsa - 3.0.3 OpenVPN - 2.4.7 2,安装 建议安装启用epel源,采用yum的方式安装o ...

  4. HTML和JS自解码机制

    1.HTML 如果用户的输入被嵌入到HTML代码中,会进行HTML解码 解码方式包括: 1.HTML实体编码: 假定下面onclick后面的内容是可控的 点击按钮 2.进制编码: 点击按钮 2.JS ...

  5. IDA入门笔记

    题目来源: 南邮CTF :: RE :: Hello,RE(应该是) XDUCTF :: ??? :: ????????(不知道不知道不知道) 总而言之我会在百度网盘再上传一份: >>百度 ...

  6. SharpDevelop 笔记

    1. 下载地址: http://jaist.dl.sourceforge.net/project/sharpdevelop/ 2. 使用 VS2012 去掉编译不通过的 Test ,其它可以运行调试. ...

  7. md5sum命令详解

    基础命令学习目录首页 原文链接:https://blog.csdn.net/cbbbc/article/details/48563023 前言 在网络传输.设备之间转存.复制大文件等时,可能会出现传输 ...

  8. 卸载CentOS7自带的OpenJDK

    http://blog.csdn.net/xiegh2014/article/details/52343438

  9. 关于rand()函数 转载于其他人

    C++中的rand()函数 分类: 编程语言/ C#/ 文章 C++中产生随机数种子对于初学者一直都很困惑.大家知道,在C中有专门的srand(N)函数可以轻松实现这一功能,然而在C++中则要复杂一些 ...

  10. jsp九大内置对象之config 和 out

    jsp中config的作用是读取web.xml中的配置信息,一般在后台获取初始化的参数,jsp页面用的较少因为jsp属于表现层,一般是获取数据. jsp中的out对象是将内容放到缓冲区中然后显示出来