排序算法分析【六】:快速排序(附Python&C++代码)

快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较。

算法原理

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

步骤为:

  1. 从数列中挑出一个元素,称为 "基准"(pivot),
  2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
  3. 递归地(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。

如果这篇博文对您有帮助,为了好的网络环境,不建议转载,建议收藏!如果您一定要转载,请带上后缀和本文地址。

时间: 2024-12-23 03:34:19

排序算法分析【六】:快速排序(附Python&C++代码)的相关文章

排序算法分析【二】:希尔排序(附Python&amp;C++代码)

希尔排序 也称递减增量排序算法,是插入排序的一种更高效的改进版本.希尔排序是非稳定排序算法. 希尔排序是基于插入排序的以下两点性质而提出改进方法的: 1.插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率: 2.插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位: 算法原理 基础是插入排序,我们先看图,图片动态展示: 这个图太快了还是不知道他在干嘛,在给一张图(图片均来自互联网): 步长选择 希尔排序中步长的选择是重中之重![来自于维基百科] 1.最终步长必

排序算法分析【五】:归并排序(附Python&amp;C++代码)

归并排序:将两个已经排序的串行合并成一个串行的操作. 算法原理 先看动态图: 算法描述如下: 申请空间,使其大小为两个已经排序串行之和,该空间用来存放合并后的串行: 设定两个指针,最初位置分别为两个已经排序串行的起始位置: 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置: 重复步骤3直到某一指针到达串行尾: 将另一串行剩下的所有元素直接复制到合并串行尾. 算法实现 Python版: #-*- encoding: utf-8 -*- def merge_sort(l

排序算法分析【一】:插入排序(附Python&amp;C++代码)

本文除了代码是自己写的,其余部分都是已存在内容.作者只是整理归纳学习,肯定不是原创,但是不是翻译,更不是转载,所以只能标注为原创,因为代码是原创.向前辈敬礼! 一.基本概念 排序算法(Sorting algorithm):将一串数据依照特定排序方式进行排列的一种算法. 排序算法是基础中的基础,重中之重.是某些算法如搜索算法.合并算法的前置算法.排序不仅仅是对数值排序,也可以是字符串. 排序算法的要求: 1.输出结果为递增(和需要排序的目标相同): 2.输出为输入的重新排列: 相关概念:[摘自百度

排序算法分析【四】:冒泡排序(附Python&amp;C++代码)

基本原理 冒泡排序(Bubble Sort,台湾另外一种译名为:泡沫排序)是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成.这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端. 这样说还不是很明白,先看张图: 算法步骤: 1)比较相邻的元素.如果第一个比第二个大,就交换他们两个: 2)对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对.

排序算法分析【三】:选择排序(附Python&amp;C++代码)

原理 选择排序(Selection sort)是一种简单直观的排序算法.它的工作原理如下. 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾.以此类推,直到所有元素均排序完毕. 选择排序的主要优点与数据移动有关.如果某个元素位于正确的最终位置上,则它不会被移动.选择排序每次交换一对元素,它们当中至少有一个将被移到其最终位置上,因此对n个元素的表进行排序总共进行至多n-1次交换.在所有的完全依靠交换去移动元素

建模分析之机器学习算法(附python&amp;R代码)

0序 随着移动互联和大数据的拓展越发觉得算法以及模型在设计和开发中的重要性.不管是现在接触比较多的安全产品还是大互联网公司经常提到的人工智能产品(甚至人类2045的的智能拐点时代).都基于算法及建模来处理.     常见的词汇:机器学习.数据建模.关联分析.算法优化等等,而这些种种又都是基于规律的深度开发(也难怪道德经的首篇就提出道可道非常道,名可名非常名的说法),不管是线性还是非线性,总之存在关联关系,而我们最好理解的就是线性关系,简单的用个函数就能解决.比如我们生活中应用的比较的归纳总结,其

机器学习经典分类算法 —— k-均值算法(附python实现代码及数据集)

目录 工作原理 python实现 算法实战 对mnist数据集进行聚类 小结 附录 工作原理 聚类是一种无监督的学习,它将相似的对象归到同一个簇中.类似于全自动分类(自动的意思是连类别都是自动构建的).K-均值算法可以发现k个不同的簇,且每个簇的中心采用簇中所含值的均值计算而成.它的工作流程的伪代码表示如下: 创建k个点作为起始质心 当任意一个点的簇分配结果发生改变时 对数据集中的每个数据点 对每个质心 计算质心与数据点之间的距离 将数据点分配到距其最近的簇 对每一个簇,计算簇中所有点的均值并将

机器学习系列(9)_机器学习算法一览(附Python和R代码)

本文资源翻译@酒酒Angie:伊利诺伊大学香槟分校统计学同学,大四在读,即将开始计算机的研究生学习.希望认识更多喜欢大数据和机器学习的朋友,互相交流学习. 内容校正调整:寒小阳 && 龙心尘 时间:2016年4月 出处:http://blog.csdn.net/han_xiaoyang/article/details/51191386 http://blog.csdn.net/longxinchen_ml/article/details/51192086 声明:版权所有,转载请联系作者并注

&lt;转&gt;机器学习系列(9)_机器学习算法一览(附Python和R代码)

转自http://blog.csdn.net/han_xiaoyang/article/details/51191386 – 谷歌的无人车和机器人得到了很多关注,但我们真正的未来却在于能够使电脑变得更聪明,更人性化的技术,机器学习. – 埃里克 施密特(谷歌首席执行官) 当计算从大型计算机转移至个人电脑再转移到云的今天,我们可能正处于人类历史上最关键的时期.之所以关键,并不是因为已经取得的成就,而是未来几年里我们即将要获得的进步和成就. 对我来说,如今最令我激动的就是计算技术和工具的普及,从而带