七种排序方法(稳定性、空间复杂度、时间复杂度)分析总结

冒泡排序:

  1. 冒泡排序只在相邻元素大小不符合要求时才调换他们的位置, 它并不改变相同元素之间的相对顺序, 因此它是稳定的排序算法.
  2. 由于冒泡排序中只有缓存的temp变量需要内存空间, 因此空间复杂度为常量O(1).
  3. 最坏的情况是每次都需要交换, 共需遍历并交换将近n²/2次, 时间复杂度为O(n²). 最佳的情况是内循环遍历一次后发现排序是对的, 因此退出循环, 时间复杂度为O(n)

对于冒泡排序为什么最佳情况可以得到O(n)复杂度的解释:
普通双层for循环确实是任意情况都是O(n²),但是可以对代码进行轻微的修改得到O(n),修改后的代码如下:

void bubbleSort(int arr[]) {
    boolean didSwap;
    for(int i = 0, len = arr.length; i < len - 1; i++) {
        didSwap = false;
        for(int j = 0; j < len - i - 1; j++) {
            if(arr[j + 1] < arr[j]) {
                swap(arr, j, j + 1);
                didSwap = true;
            }
        }
        if(didSwap == false)
        return;
    }
}

选择排序:

  1. 每次从未排序的数中选择最小的与未排序的第一个交换,破坏了相对顺序(比如未排序的第一个是3,第二个也是3,第三个是2也是未排序中最小的,此时交换第三个和第一个,会破坏第一个和第二个之间的相对顺序),所以不是稳定的排序
  2. 空间复杂度为常量O(1)(同冒泡排序只有交换的时候临时变量需要空间)
  3. 无论是哪种情况,哪怕原数组已排序完成,它也将花费将近n²/2次遍历来确认一遍,时间复杂度为O(n²)

插入排序:

  1. 每次交换不改变其他元素间的相对顺序,因此是稳定的排序算法
  2. 空间复杂度为常量O(1)
  3. 最坏的情况是每次都需要交换, 共需遍历并交换将近n²/2次, 时间复杂度为O(n²),最好的情况是已经排序好,只要遍历一次,不需要交换,时间复杂度为O(n)

希尔排序:

  1. 相同的元素会分到不同的子序列,可能会破坏相对顺序,故为不稳定的排序算法
  2. 空间复杂度为常量O(1)(内部是插入排序)
  3. 最坏情况和平均时间复杂度都是O(nlog2 n),最好情况不确定

归并排序:

  1. 分割和归并的时候都不会改变相对顺序,故是稳定的排序算法
  2. 需要一个辅助数组,空间复杂度是O(n),递归需要保存的空间为O(log2 n),所以加起来仍然是O(n)
  3. 假设数组长度为n,那么拆分数组共需log2 n,, 又每步都是一个普通的合并子数组的过程, 时间复杂度为O(n), 故其综合时间复杂度为O(nlog2 n)
    1. 通过自上而下的递归实现的归并排序, 将存在堆栈溢出的风险。

快速排序:

  1. 同选择排序相似, 快速排序每次交换的元素都有可能不是相邻的, 因此它有可能打破原来值为相同的元素之间的顺序. 因此, 快速排序并不稳定
  2. 首先就地快速排序使用的空间是O(1);而真正消耗空间的就是递归调用了,因为每次递归就要保持一些数据;最优的情况下空间复杂度为O(log2 n),每一次都平分数组;最差的情况下空间复杂度为O( n ),退化为冒泡排序的情况
  3. 平均时间复杂为O(nlog2 n),最糟糕时将达到O(n²)的时间复杂度

堆排序:

  1. 并不是邻近交换,故为不稳定排序
  2. 不需要辅助数组,空间复杂度为O(1)
  3. 建立堆的过程, 从n/2 一直处理到0, 时间复杂度为O(n),调整堆的过程是沿着堆的父子节点进行调整, 执行次数为堆的深度log2 n,一共要执行n次,加起来时间复杂度未O(nlog2 n)

图片总结

这里写图片描述

参考

  1. 八大排序算法总结与java实现
  2. 七种常见经典排序算法总结(C++实现)
  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值