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

算法如下:

快速排序排序 从大到小

1. 先让从最右边的哨兵开始出发往左移动,直到找到一个小于 A[base] 的数,或者碰到左边的哨兵
2. 再从最左边的哨兵开始出发往右移动,直到找到一个大于 A[base] 的数,或者碰到右边的哨兵
3. 如果没有相遇,这将两个哨兵所在的元素交换,使得较小的元素分到了左边,较大的元素分到了右边
4. 当两个哨兵相遇,则结束循环,把序列分成两个部分,即 低端序列(都是较小元素) 和 高端序列(都是较大元素)
5. 递归,分别对 低端序列 和 高端序列 进行同样的过程

贴代码:

  1. def quicksort_rec(A,lft=None,rgt=None):
  2.  
  3. if lft == None or rgt == None:
  4. lft, rgt = 0, len(A)-1
  5. if lft >= rgt:
  6. return
  7.  
  8. i = lft # 序列最左边的哨兵
  9. j = rgt # 序列最右边的哨兵
  10. base = lft # 基准数的索引
  11. while i != j:
  12. while A[j] >= A[base] and i < j: # 先从右往左找
  13. j -= 1
  14. while A[i] <= A[base] and i < j:
  15. i += 1
  16. if i < j: # 没有相遇:交换
  17. A[i], A[j] = A[j], A[i]
  18.  
  19. A[base], A[i] = A[i], A[base] # 基准数归位, 索引 i 为序列正中
  20. quicksort_rec(A, lft, i-1) # 递归处理左边序列
  21. quicksort_rec(A, i+1, rgt) # 递归处理右边序列

很短对不对,下面是运行结果:

  1. A = [6,1,2,7,9,3,4,2,5,10,8,1]
  2. quicksort_rec(A)
  3. print A
  4.  
  5. >>> [1, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10]

另一种更简洁的实现方式:

  1. # 分离数列seq为低端序列和高端序列
  2. def partition(seq):
  3. pi, seq = seq[0], seq[1:] # 选择数列中第0个数据为基准元素
  4. lo = [x for x in seq if x <= pi] # 选出seq中较小元素
  5. hi = [x for x in seq if x > pi] # 选出seq中较大元素
  6. return lo,pi,hi
  7.  
  8. # 快速排序法
  9. def quicksort(seq):
  10. if len(seq)<=1: return seq
  11. lo, pi, hi = partition(seq)
  12. return quicksort(lo) + [pi] + quicksort(hi)
  13.  
  14. # 测试
  15. seq = [1,2,4,6,3,7,5,9,0,5,7]
  16. print quicksort(seq)
  17.  
  18. >>> [0, 1, 2, 3, 4, 5, 5, 6, 7, 7, 9]

利用上面的函数partition,可以使用二分法查找第k个最小的元素(不排序)

  1. # 选择数组中第k小元素
  2. def select(seq, k):
  3. lo, pi, hi = partition(seq) # [<= pi], pi, [> pi]
  4. m = len(lo)
  5. if m == k: return pi # 找到第k最小值
  6. elif m < k:
  7. return select(hi,k-m-1)
  8. else:
  9. return select(lo,k)

调用方法:

  1. # 原数组:seq = [1,2,4,6,3,7,5,9,0,5,7]
  2. # 排序后:[0, 1, 2, 3, 4, 5, 5, 6, 7, 7, 9]
  3. print select(seq,6)
  4.  
  5. >>> 5

python数据结构与算法——快速排序的更多相关文章

  1. python数据结构与算法

    最近忙着准备各种笔试的东西,主要看什么数据结构啊,算法啦,balahbalah啊,以前一直就没看过这些,就挑了本简单的<啊哈算法>入门,不过里面的数据结构和算法都是用C语言写的,而自己对p ...

  2. Python数据结构与算法--List和Dictionaries

    Lists 当实现 list 的数据结构的时候Python 的设计者有很多的选择. 每一个选择都有可能影响着 list 操作执行的快慢. 当然他们也试图优化一些不常见的操作. 但是当权衡的时候,它们还 ...

  3. Python数据结构与算法--算法分析

    在计算机科学中,算法分析(Analysis of algorithm)是分析执行一个给定算法需要消耗的计算资源数量(例如计算时间,存储器使用等)的过程.算法的效率或复杂度在理论上表示为一个函数.其定义 ...

  4. Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例

    本文实例讲述了Python数据结构与算法之图的最短路径(Dijkstra算法).分享给大家供大家参考,具体如下: # coding:utf-8 # Dijkstra算法--通过边实现松弛 # 指定一个 ...

  5. Python数据结构与算法之图的广度优先与深度优先搜索算法示例

    本文实例讲述了Python数据结构与算法之图的广度优先与深度优先搜索算法.分享给大家供大家参考,具体如下: 根据维基百科的伪代码实现: 广度优先BFS: 使用队列,集合 标记初始结点已被发现,放入队列 ...

  6. Python 数据结构和算法

    阅读目录 什么是算法 算法效率衡量 算法分析 常见时间复杂度 Python内置类型性能分析 数据结构 顺序表 链表 栈 队列 双端队列 排序与搜索 冒泡排序 选择排序 插入排序 希尔排序 快速排序 归 ...

  7. Python数据结构与算法(几种排序)

    数据结构与算法(Python) 冒泡排序 冒泡排序(英语:Bubble Sort)是一种简单的排序算法.它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.遍历数列的工作是 ...

  8. Python数据结构与算法?

    数据结构与算法(Python) 冒泡排序 冒泡排序(英语:Bubble Sort)是一种简单的排序算法.它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.遍历数列的工作是 ...

  9. python数据结构与算法之问题求解实例

    关于问题求解,书中有一个实际的案例. 上图是一个交叉路口的模型,现在问题是,怎么安排红绿灯才可以保证相应的行驶路线互不交错. 第一步,就是把问题弄清楚. 怎么能让每一条行驶路线不冲突呢? 其实,就是给 ...

随机推荐

  1. Kanzi UI Solution

    Kanzi UI Solution是一个完整的跨平台的UI解决方案, 基于OpenGL 和 OpenGL ES.Kanzi为UI的设计.开发和部署在嵌入式设备上的图形用户界面提供一个完善的开发平台. ...

  2. 简单的SpringMVC的测试项目----跟struts2对比着学习

    一,搭建SpringMVC项目 1,主配置文件-----地基 because,不像struts2是个独立的框架,可以脱离Spring单独使用.需要先添加Spring支持,是Spring框架组成的一部分 ...

  3. 一个webpack,react,less,es6的DEMO

    1.package.json如下 { "name": "demo", "version": "1.0.0", " ...

  4. GC overhead limit exceeded填坑心得

    我遇到这样的问题,本地部署时抛出异常java.lang.OutOfMemoryError:GC overhead limit exceeded导致服务起不来,查看日志发现加载了太多资源到内存,本地的性 ...

  5. .net 连接数据库

    "@"符号是防止将后面字符串中的"\"解析为转义字符. using System.Data; using System.Data.SqlClient; ... ...

  6. php注意事项2

    1.不要使用相对路径 常常会看到: require_once('../../lib/some_class.php'); 该方法有很多缺点: 它首先查找指定的php包含路径, 然后查找当前目录. 因此会 ...

  7. springboot

    http://7player.cn/2015/08/30/%E3%80%90%E5%8E%9F%E5%88%9B%E3%80%91%E5%9F%BA%E4%BA%8Espringboot-mybati ...

  8. struts2学习:配置篇之namespace

    把namespace单独拉出来讲一方面是因为它实际上不是一个element,而只是一个attribute,前面已经说了,它是package的一个attribute:另外一方面是因为这个属性是我接触St ...

  9. eclipse注释模板及格式化模板导入步骤

    1.点击Window->Preference->Java -> Code Style -> Formatter 2.点击右侧Import选择*.xml模板文件导入即可 3.如果 ...

  10. 第三节 构造一个简单的Linux系统MenuOS——20135203齐岳

    第三节 构造一个简单的Linux系统MenuOS By 20135203齐岳 Linux内核源代码 arch/ 支持不同cpu的源代码 Documentations/ 文档存储 init/ 内核启动相 ...