算法入门8-排序总结

  基于比较的排序:选择排序、冒泡排序、插入排序、归并排序、快速排序、堆排序。

  非基于比较的排序:计数排序、基数排序。

  非基于比较的排序,指不直接对比两条记录的排序算法,一般只适用于数值型数组,适用范围有限,下面我们主要谈论基于比较的排序。

  排序总结图:

在这里插入图片描述

一、稳定性

 稳定性,指相同关键字的记录排序后,仍保持相对次序。

  下面我们分析不同排序算法的稳定性:

  1、选择排序:选择排序是在一个数组中选定一个位置,比如从0位开始,排好当前位置顺序后,再往后继续排序。看下图java实现代码:

// 选择排序
public static void sort(Integer[] arr) {
    for(int i = 0; i < arr.length - 1; i++) {
        for(int j = i+1; j < arr.length; j++) {
            if(arr[i] > arr[j]) {
                DataStore.swap(arr, i, j);
            }
        }
    }
}

  可以看到,选择排序对比的是arr[i] 和 arr[j]的大小,不是相邻数之间的对比,势必会打破稳定性。

  2、冒泡排序:冒泡排序是将符合条件的值不断冒出的过程,实现过程是对比相邻数,如果碰到相等的值,不交换位置,所以能保持稳定性。java实现代码:

// 冒泡排序
public static void sort(Integer[] arr) {
    for(int i=0; i<arr.length-1; i++) {
        for(int j=0; j<arr.length-1-i; j++) {
            if(arr[j] > arr[j+1]) {
                DataStore.swap(arr, j, j+1);
            }
        }
    }
}

  3、插入排序:插入排序是往有序数组中插入值的过程。实现过程也是相邻数之间的对比,所以也能保持稳定性。java实现代码:

// 插入排序
public static void sort(Integer[] arr) {
    for(int i = 1; i < arr.length; i++) {
        for(int j = i-1; j >= 0; j--) {
            if(arr[j] > arr[j+1]) {
                DataStore.swap(arr, j, j+1);
            }
        }
    }
}

  4、归并排序:归并排序是将数组不断二分,然后再重新有序合并的过程。在归并方法中,只要做到,碰到相等值时,先插入左区间的值,则能保持稳定性。

  5、快速排序:快速排序通过对数组分割出基准值小于区、相等区、大于区的方法,找出基准值在数组中索引,从而排序的过程。在分三区的过程中,不是相邻数之间的对比,数组被大幅度改变,不能保证稳定性。

  6、堆排序:堆排序是将数组转化成堆,从而利用堆结构排序的过程。在数组转化成堆的过程,已经破坏了稳定性。

二、优先选择

  排序算法这么多种,那我们如何选择呢?

  第一个要看的指标,肯定是时间复杂度。基于比较的排序中,最小的时间复杂度是O(N*logN)。

  一般的,我们会优先选择快速排序,因为在实验结果下,快速排序常数项时间最低,速度最快。

  如果有空间限制的时候,选择堆排序,它的空间复杂度只有O(1)。

  如果要求稳定性的时候,选择归并排序。

三、推论

  1、基于比较的排序,没有排序算法的时间复杂度能低于O(N*logN)。

  时间复杂度低于O(N*logN)的排序算法,一定是非基于比较的排序算法,比如:

  计数排序,Ο(n+k)(其中k是整数的范围);

  基数排序,O(m * (n + k))(m为执行的计数排序次数,k为位数上的取值范围)。

  2、基于比较的排序,没有排序算法的时间复杂度低于O(N^2)并且空间复杂度低于O(N)的情况下能保持稳定性。

   从排序总结表中可以看出,时间复杂度低于O(N^2)的排序算法是归并排序、快速排序、堆排序,其中能保持稳定性的是归并排序,空间复杂度是O(N)。

四、工程上对排序的改进

1、充分利用O(NlogN)和O(N^2)排序各自的优势。

  比如对快速排序做优化,当样本量小于60时,直接使用插入排序返回。这是因为当样本量小时,插入排序更具优势。

  在c、c++、java等语言中的排序实现,都是利用不同排序的优势,形成综合排序。

2、稳定性的考虑

  系统array.sort方法中,当判断到是基础类型排序时,使用快速排序。因为快速排序有更快的速度,而且,基础类型不需要保持稳定性。当判断到是非基础类型排序时,使用归并排序,保持稳定性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值