首页 > 代码库 > 排序算法分析【六】:快速排序(附Python&C++代码)
排序算法分析【六】:快速排序(附Python&C++代码)
快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较。
算法原理
快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。
步骤为:
- 从数列中挑出一个元素,称为 "基准"(pivot),
- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
- 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
图片详解:问题:怎么找到基准?
无所谓,可以随机取,也可以取首元素。【具体想一想就明白了】
算法实现
Python版:
【PS,由于是算法,我不赞同更多利用Python特性来写,Pythonic的代码不超过10行就搞定了,最后附上!】
#-*- encoding: utf-8 -*- def quick_sort(st_bf): # 快速排序 j = 0 # 标记哨兵位置 if len(st_bf) > 1: tag = st_bf[0] # 设置哨兵 for i in xrange(1, len(st_bf)): if st_bf[i] < tag: temp = st_bf[i] # 小于tag位置挪到tag前面,也就是tag和比tag大的整体后移 for k in xrange(i, j, -1): st_bf[k] = st_bf[k-1] st_bf[j] = temp # 小元素移到哨兵前面 j += 1 else: # 大于tag不用处理 pass else: return st_bf # 递归处理左右子区间 print 'st_bf = ', st_bf left = quick_sort(st_bf[:j:]) right = quick_sort(st_bf[j+1::]) print left + [st_bf[j]] + right return left + [st_bf[j]] + right st_bf = [4, 5, 9, 2, 6, 8, 1, 7, 3] print quick_sort(st_bf)结果为:
>>> ================================ RESTART ================================ >>> st_bf = [2, 1, 3, 4, 5, 9, 6, 8, 7] st_bf = [1, 2, 3] [1, 2, 3] st_bf = [5, 9, 6, 8, 7] st_bf = [6, 8, 7, 9] st_bf = [6, 8, 7] st_bf = [7, 8] [7, 8] [6, 7, 8] [6, 7, 8, 9] [5, 6, 7, 8, 9] [1, 2, 3, 4, 5, 6, 7, 8, 9] [1, 2, 3, 4, 5, 6, 7, 8, 9] >>>
Pythonic版:充分利用List Comprehensions(点击查看详细)
#-*- encoding: utf-8 -*- def quick_sort(st_bf): # 快速排序 if len(st_bf) > 1: temp = st_bf[0] st_now = quick_sort([i for i in st_bf[1:] if i < temp]) + [temp] + quick_sort([j for j in st_bf[1:] if j >= temp]) return st_now else: return st_bf st_bf = [4, 5, 9, 2, 6, 8, 1, 7, 3] print quick_sort(st_bf)以上代码这样写比C版本(我都是按C语言特点写的)简单太多了!但是这毕竟用了高级特性,没有真正的学习算法!不推荐,在此展示下Pythonic的魅力!
C++实现:
#include <iostream> using namespace std; void print (int st_bf[], size_t size){ for (size_t i = 0; i < size; i++) { cout<< st_bf[i] << " "; } cout<< endl; } void quick_sort(int *st_bf, size_t size){ //快速排序 size_t j = 0; // 标记哨兵位置 if (size > 1){ int tag = st_bf[0]; // 设置哨兵 for (size_t i = 1; i < size; ++i){ if (st_bf[i] < tag){ int temp = st_bf[i]; // 小于tag位置挪到tag前面,也就是tag和比tag大的整体后移 for (size_t k = i; k > j; --k){ st_bf[k] = st_bf[k-1]; } st_bf[j] = temp; // 小元素移到哨兵前面 j += 1; } else {/*大于tag不用处理*/} } } else {/*空数组,无需处理*/} // 递归处理左右子区间 if (j > 0) quick_sort(st_bf, j); size_t len_right = size-j-1; if (len_right > 0) quick_sort(st_bf+j+1, len_right); } int main(){ int st_bf[] = {4, 5, 9, 2, 6, 8, 1, 7, 3}; size_t size = sizeof(st_bf)/sizeof(st_bf[0]); quick_sort(st_bf, size); print(st_bf, size); return 0; }结果一样,不在贴出。
本文由@The_Third_Wave(Blog地址:http://blog.csdn.net/zhanh1218)原创。还有未涉及的,会不定期更新,有错误请指正。
如果你看到这篇博文时发现没有不完整,那是我为防止爬虫先发布一半的原因,请看原作者Blog。
如果这篇博文对您有帮助,为了好的网络环境,不建议转载,建议收藏!如果您一定要转载,请带上后缀和本文地址。
排序算法分析【六】:快速排序(附Python&C++代码)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。