一、写法
- 选择排序:遍历当前数组,每次把 当前位置右边最小数放到当前位置,排好当前位置,保证本位置及前面的有序。
- 冒泡排序:遍历当前数组,每次把 当前位置 和 下一个位置 比较,如果后一个比前一个大,则交换位置,每轮比较后,后面的元素是有序的。
- 插入排序:每次让前i个数有序,和选择排序不同,选择排序是选后面最小的放前面,保证最小的先有序;插入排序是比较当前位置和前面的,在这段中,是有序的。
- 归并排序:每次把数组分成两段,有个辅助数组,那两端开始按位对比,谁小谁放数组中,再归并。
- 快速排序:每次以末尾数字为基数,每次分割为三部分(小于当前值部分,等于当前值部分,大于当前值部分),比当前值小的放左边,大的放右边。
- 堆排序:数组存储数,左节点坐标=父结点*2+1,右节点左边=左+1,父结点=(子-1)/2。总体分为两步:先建堆,再输出。建堆,即从上往下建堆,插入结点,比如建立大顶堆,插入时比较当前结点和父结点大小,子节点比父结点大就交换位置,当前结点移动到父结点位置。也可以从下往上建堆,判断一个结点是不是最后一个结点,如果不是,就比较左右父结点的大小,最大的放上面,当前结点标记为最大结点。
- 计数排序:借助数组的有序性,建立足够大的数组,类似哈希表思路,这里是直接把对应值放到对应索引下标下,数量++,最后遍历输出就行。当然,如果有负数,还得先找到最小负数,所有数先加其绝对值,保证最小值为0,最后需要处理,每个数再减去这个绝对值。
- 基数排序:蛮复杂的,可以准备十个桶分别放 当前位为 0-9 的数,也可以只用一个数组,预留好对应的位置,从低位往高位循环,每次把数放到对应的位置,再拿出来。
- 准备好辅助数组help,用来存 当前位为 0-9 的数
- 获取本数组中最大数值的位数,并以此来循环,表示每次 当前位 的元素取出,放入对应桶(位置)
2.1. 根据 当前位 元素,放入对应桶(数组对应位置)count数组是专门用来存预留多少位的
2.2. 依次计算count[]数组,值为之前的值+当前值,用以表示需要预留多少位
2.3. 从右往左遍历原数组 arr,放到help数组中
2.4. 把help数组中的本次放入取出的结果 赋值回 原数组
二、对比
三、实际使用
- 不基于比较的数,对样本数据有严格要求,不易改写。
- 基于比较的排序,时间复杂度的极限为O(N*logN)
其中归并排序、快速排序、堆排序 都是这个时间复杂度,要稳定就用快排,速度最快的是快排,但不稳定,堆排序最节省内存。 - 时间复杂度O(N*logN),空间复杂度低于O(N)且稳定的基于比较的排序是不存在的。