zoukankan      html  css  js  c++  java
  • 算法系列之(2): 排序算法简介

    简介:

    在算法的世界里,排序是最基本又是最重要的一类。在TACP(The Art of Computing Programming)中,占据了专门且重要的篇幅。在面试中也是屡屡出现。一般而言,排序是查找的基础,比如著名的二分查找,就是建立在有序序列的基础上的。

    在众多的排序算法中,可以按照时间复杂度大概分为三类:

    n平方阶的算法,

    nlgn的算法(基于比较算法的下界)

    线性时间的算法。

    如果按排序的其他性质来分,又可以分为稳定排序/非稳定排序,等等。

    知名的说法有常说的8大排序算法,专门指内部排序(与在磁盘上的外部排序相比,这些排序全部在内存中完成)。包括:

    插入排序直接插入排序希尔排序  12

    选择排序简单选择排序堆排序  34

    交换排序冒泡排序快速排序  56

    归并排序 7

    基数排序(是基于桶排序的) 8

    1 O(n^2)

    1.1 冒泡

    基本思想:在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。每一趟排序后的效果都是讲没有沉下去的元素给沉下去。

      算法流程:

      1)比较相邻的两个元素,如果前面的数据大于后面的数据,就将两个数据进行交换;这样对数组第0个元素到第n-1个元素进行一次遍历后,最大的一个元素就沉到数组的第n-1个位置;

      2)重复第2)操作,直到i=n-1。

      时间复杂度分析:O(n^2),冒泡排序是一种不稳定排序算法。

    可以看到,冒泡排序跟选择排序有相似的地方,在经过一轮迭代以后,都是把最大元素排在最后。

    冒泡排序的代码简单易懂,更适合作为教学目的之用。

    2 O(nlogn)

    归并(Merge)

    是二分法的在排序算法中的一种典型应用。

    快排

    堆排

    3 O(n)的算法

     在CLRS一书中,四位作者已经证明了,对于基于比较的排序算法而言,它的下界就是O(nlgn),也就是说像归并之类的排序算法已经是最快了。但是如果打破基于比较去排序的这种思想藩篱,则其实还可以得到更快的排序算法:时间复杂度为线性的排序算法。

    但是需要注意的是,这些算法的应用都有一些场景上的限制,即只有满足特定的条件,才能应用这些算法。。类似于快排一样的、通用的线性时间复杂度的排序算法是不存在的。

    这类算法主要有:

    桶排序

    计数排序是桶排序的一种特殊情况,可以把计数排序当成每个桶里只有一个元素的情况。

    桶排序要求数据的分布必须均匀,否则可能导致数据都集中到一个桶中。比如[104,150,123,132,20000], 这种数据会导致前4个数都集中到同一个桶中。导致桶排序失效。

    网络各博文中流程的桶排序算法实际上都是计数排序,并非标准的桶排序。

    基数

    计数排序

    它仅适用于数据比较集中的情况。比如 [0~100],[10000~19999] 这样的数据。

    3.1 原理

    计数排序、基数排序、桶排序则属于非比较排序。非比较排序是通过确定每个元素之前,应该有多少个元素来排序。针对数组arr,计算arr[i]之前有多少个元素,则唯一确定了arr[i]在排序后数组中的位置。
    非比较排序只要确定每个元素之前的已有的元素个数即可,所有一次遍历即可解决。算法时间复杂度O(n)
    非比较排序时间复杂度底,但由于非比较排序需要占用空间来确定唯一位置。所以对数据规模和数据分布有一定的要求。

    参考文献

    http://www.cnblogs.com/Leo_wl/p/4716681.html

  • 相关阅读:
    commons-logging.jar 和 log4j.jar 的关系
    百钱买百鸡
    reflect
    golang结构体、接口、反射
    golang文件操作
    sqlx使用说明
    go example
    goroutine
    生成二维码
    method&interface
  • 原文地址:https://www.cnblogs.com/hzg1981/p/5329112.html
Copyright © 2011-2022 走看看