python 实现快速排序
来源:互联网 发布:ubuntu挂起后怎么唤醒 编辑:程序博客网 时间:2024/05/16 06:51
第一版
#!/usr/bin/env python# encoding: utf-8 def part(ll, begin, end): k = ll[end] i = begin - 1 for j in range(begin, end): if ll[j] <= k: i += 1 ll[j], ll[i] = ll[i], ll[j] ll[end], ll[i + 1] = ll[i + 1], ll[end] return i + 1 def qsort1(ll, l, r): if l < r: mid = part(ll, l, r) qsort1(ll, l, mid - 1) qsort1(ll, mid + 1, r) L = [3, 965767,43783, 9, 511, 100, 8, 47483, 2090, 4332, 1111, 3323, 1990, 432, 11113, 43892, 99, 348, 10437892, 87899] qsort1(L, 0, len(L) - 1)print L
第二版
def qsort2(ll): if len(ll) <= 1: return ll else: pivot = ll[0] return qsort2([x for x in ll[1:] if x < pivot]) + [pivot] + qsort2([x for x in ll[1:] if x >= pivot])L = [3, 965767,43783, 9, 511, 100, 8, 47483, 2090, 4332, 1111, 3323, 1990, 432, 11113, 43892, 99, 348, 10437892, 87899]print qsort2(L)
快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。
从数列中挑出一个元素,称为 "基准"(pivot),
重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
在简单的伪代码中,此算法可以被表示为:
function quicksort(q)
var list less, pivotList, greater
if length(q) ≤ 1 {
return q
} else {
select a pivot value pivot from q
for each x in q except the pivot element
if x < pivot then add x to less
if x ≥ pivot then add x to greater
add pivot to pivotList
return concatenate(quicksort(less), pivotList, quicksort(greater))
}
原地(in-place)分区的版本
上面简单版本的缺点是,它需要Ω(n)的额外存储空间,也就跟归并排序一样不好。额外需要的存储器空间配置,在实际上的实现,也会极度影响速度和高速缓存的性能。有一个比较复杂使用原地(in-place)分区算法的版本,且在好的基准选择上,平均可以达到O(log n)空间的使用复杂度。
function partition(a, left, right, pivotIndex)
pivotValue := a[pivotIndex]
swap(a[pivotIndex], a[right]) // 把 pivot 移到結尾
storeIndex := left
for i from left to right-1
if a[i] < pivotValue
swap(a[storeIndex], a[i])
storeIndex := storeIndex + 1
swap(a[right], a[storeIndex]) // 把 pivot 移到它最後的地方
return storeIndex
这是原地分区算法,它分区了标示为 "左边(left)" 和 "右边(right)" 的串行部份,借由移动小于a[pivotIndex]的所有元素到子串行的开头,留下所有大于或等于的元素接在他们后面。在这个过程它也为基准元素找寻最后摆放的位置,也就是它回传的值。它暂时地把基准元素移到子串行的结尾,而不会被前述方式影响到。由于算法只使用交换,因此最后的数列与原先的数列拥有一样的元素。要注意的是,一个元素在到达它的最后位置前,可能会被交换很多次。
一旦我们有了这个分区算法,要写快速排列本身就很容易:
procedure quicksort(a, left, right)
if right > left
select a pivot value a[pivotIndex]
pivotNewIndex := partition(a, left, right, pivotIndex)
quicksort(a, left, pivotNewIndex-1)
quicksort(a, pivotNewIndex+1, right)
- 快速排序Python实现
- python实现快速排序
- Python实现快速排序
- python 实现快速排序
- Python实现快速排序
- 快速排序Python实现
- python实现快速排序
- Python实现快速排序
- python实现快速排序
- python 实现快速排序
- Python实现快速排序
- python实现快速排序
- Python实现快速排序
- python实现快速排序
- Python实现快速排序
- Python实现快速排序
- python实现快速排序
- 快速排序的python实现
- VS2010"LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏"解决方法
- maven 打包 protobuf
- android的PreferenceActivity
- HDOJ 1176 免费馅饼 (dp)
- louboutin france mais n'a pas ne carrières
- python 实现快速排序
- christian louboutin pas cher d'abord
- 安装了ansys 后出现错误提示: could not create the file required to ......
- CentOS rpm 额外包的源
- Objective-C NSDateAndDateFormatter
- Apache Commons-pool实现对象池(包括带key对象池)
- SEO学习笔记(二)
- 《STL源码剖析》---stl_list.h阅读笔记
- Java正则表达式最基本用法