zoukankan      html  css  js  c++  java
  • 【每日算法】排序算法总结(复杂度&稳定性)

    一、插入排序:稳定,时间复杂度O(n^2)

    想象你在打扑克牌,一開始左手是空的,接着右手開始从桌上摸牌,并将其插入到左手的一把牌中的正确位置上。为了找到这个正确位置,我们须要从右到左将它与手中的牌比較,直到找到合适的位置插入。整个过程的特点是,左手的牌是排好序的了。

    详见: 插入排序

    二、选择排序:不稳定,时间复杂度O(n^2)

    每趟从未排序部分选出最小的元素。然后通过交换将其加入到已排序部分中。

    详见: 选择排序

    三、冒泡排序:稳定,时间复杂度O(n^2)

    将待排序的元素看作是竖着排列的“气泡”。较小的元素比較轻。从而要往上浮。在冒泡排序算法中我们要对这个“气泡”序列处理若干遍。所谓一遍处理,就是自底向上检查一遍这个序列,并时刻注意两个相邻的元素的顺序是否正确。

    假设发现两个相邻元素的顺序不正确。即“轻”的元素在以下,就交换它们的位置。显然。处理一遍之后,“最轻”的元素就浮到了最高位置;处理两遍之后。“次轻”的元素就浮到了次高位置。在作第二遍处理时,由于最高位置上的元素已是“最轻”元素,所以不必检查。

    一般地。第i遍处理时,不必检查第i高位置以上的元素。由于经过前面i-1遍的处理,它们已正确地排好序。

    详见: 冒泡排序

    四、归并排序:稳定。时间复杂度 O(nlog n),空间O(n)

    分解:将n个元素分成各含n/2个元素的子序列。
    解决:用归并排序法对两个子序列递归地排序。
    合并:合并两个已排序的子序列以得到排序结果。

    合并思想:

    桌面上有两堆已排好序的牌(比方最上面的牌最小),牌面朝上。

    我们的任务是将两堆牌合并成一堆有序的牌。

    以下開始取牌:从两堆牌顶上的两张牌中选取较小的一张,将其取出,面朝下放到输出堆中。假设重复取牌直到当中一堆牌为空,接下来仅仅要把剩下那堆牌(假设有的话)的全部牌都取出并放到输出堆中就可以。

    详见: 归并排序

    五、堆排序:不稳定,时间复杂度 O(nlog n)

    堆排序是一种树形选择排序,在排序过程中。将A[n]看成是全然二叉树的顺序存储结构,利用全然二叉树中双亲结点和孩子结点之间的内在关系来选择最大的元素。

    详见: 堆排序

    六、高速排序:不稳定,时间复杂度 平均O(nlog n),最差O(n^2)。空间O(log n)->递归的栈空间

    快排基于分治模式。其基本思想:
    分解:从序列中取出一个数作为基准数,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边,从而得到两个子序列。
    解决:递归调用高速排序。对两个子序列进行排序。
    合并:由于子序列是就地排序的,所以合并不须要不论什么操作。

    详见: 高速排序

    七、希尔排序:不稳定。时间复杂度 平均O(nlogn),最差O(n^s) 1 < s < 2

    在直接插入排序算法中。每次插入一个数。使有序序列仅仅添加1个节点。而且对插入下一个数没有提供不论什么帮助。假设比較相隔较远距离(称为 增量)的数,使得数移动时能跨过多个元素,则进行一次比較就可能消除多个元素交换。D.L.shell于1959年在以他名字命名的排序算法中实现了这一思想。算法先取某个增量d,全部距离为d的倍数的记录放在同一个组中。先在各组内进行直接插入排序,然后再用一个较小的增量对它分组,在每组中再进行排序。当增量减到1时,整个要排序的数被分成一组。排序完毕。

    八、计数排序:稳定,线性时间

    计数排序假设n个输入元素都是0到k之间的整数,基本思想是对每一个元素x。确定出小于x的元素个数。之后便能够将x直接放到合适的位置。(需注意元素相等的情况)

    详见: 计数排序

    八、基数排序:稳定,线性时间

    我们要对一副扑克牌排序,能够这样做:先无论牌的大小,先对花色(比方红桃、黑桃、方块、梅花)排序。之后再依据牌的大小排序。于是一副牌就按花色、大小排好了。

    对于数字。我们能够先对最低位排序,再对次低位排序。。最后对最高位排序。

    详见: 基数排序

    八、桶排序:稳定。线性时间

    假设全部元素均匀分布在区间[0,1)上,将该区间划分成n个同样大小的子区间(称为桶),之后。将相应的元素放到相应范围的桶里面,对各个桶里的元素进行排序,最后按次序把各个桶里的元素列出来就可以。

    桶排序非常快。大多时候比快排还快。只是非常耗费空间。

    详见: 桶排序

    各个算法都有其适用的情况,所以没有绝对的优劣之分,详细问题要详细分析。

    要是有人问你,哪个排序算法最好。千万别往坑里跳。o(^▽^)o


    以下提一下一些有趣的排序:

    位图排序

    (以下是并行化的排序算法)

    双调排序(Bitonic Sort)

    奇偶排序(Odd-even Sort)

    採样排序(Sample Sort)


    每天进步一点点,Come on!

    (●’◡’●)
    

    本人水平有限,如文章内容有错漏之处,敬请各位读者指出,谢谢!

  • 相关阅读:
    python学习笔记6基本对象和流程语句整理
    暑假第二周总结(2018.7.16——7.22)
    暑假第三周总结(2018.7.23——7.29)
    《大道至简》读后感
    暑假第四周总结(2018.7.30——8.5)
    暑假第一周总结(2018.7.97.15)
    .NET中实现页面间的参数传递 QueryString\Application\Session\Cookie(转载)
    px和dip的区别与转换公式
    android开发ListView+Json+异步网络图片加载+滚动翻页的例子(图片能缓存,图片不错乱)
    正则表达式的惰性匹配方法
  • 原文地址:https://www.cnblogs.com/gavanwanggw/p/7160162.html
Copyright © 2011-2022 走看看