快速排序(Quick Sort)

[简介]算法

  快速排序英语:Quicksort),又称划分交换排序(partition-exchange sort),最先由东尼·霍尔提出。在平均情况下,排序n个项目要Ο(n log n)次比较。在最坏情况下则须要Ο(n2)次比较,但这种情况并不常见。事实上,快速排序一般明显比其余Ο(n log n)算法更快,由于它的内部循环(inner loop)能够在大部分的架构上颇有效率地被实现出来。架构

 

[算法复杂度]ide

  仅针对非原地版本进行讨论oop

  

  非原地版本的快速排序,在它的任何递归调用前须要使用O(n)空间。在最好的状况下,它的空间仍然限制在O(n),由于递归的每一阶中,使用与上一次所使用最多空间的一半,且ui

\sum _{i=0}^{\infty }{\frac {n}{2^{i}}}=2n

  它的最坏状况是很恐怖的,须要spa

\sum _{i=0}^{n}(n-i+1)=\Theta (n^{2})

  空间,远比数列自己还多。若是这些数列元素自己本身不是固定的大小,这个问题会变得更大;举例来讲,若是数列元素的大部分都是不一样的,每个将会须要大约O(log n)为原来存储,致使最好状况是O(n log n)和最坏状况是O(n2 log n)的空间需求。code

 

[核心算法]xml

  

  快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists)。blog

  步骤为:排序

  1. 从数列中挑出一个元素,称为"基准"(pivot),
  2. 从新排序数列,全部元素比基准值小的摆放在基准前面,全部元素比基准值大的摆在基准的后面(相同的数能够到任一边)。在这个分区结束以后,该基准就处于数列的中间位置。这个称为分区(partition)操做。
  3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

  递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,可是这个算法总会结束,由于在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

 

 [Source Code]

def quick_sort(alist=None):
    blist = alist[:]
    N = len(blist)
    if N <= 1:
        return blist
    pivot = blist[0]
    return quick_sort([x for x in blist[1:] if x < pivot]) + [pivot] + quick_sort([x for x in blist[1:] if x >= pivot])

 

[示意图]

相关文章
相关标签/搜索