使一串数据,按照递增或者递减的顺序排列起来,这个操作称为排序,通常意义上的排序,指的是原地排序。
===========本篇文章均以升序为例==========
目录
1. 性能分析的方法
1.1 时间复杂度
1.2 空间复杂度
1.3 稳定性
两个相等的数据,排序前和排序后的相对位置相同,那么就称这种排序是稳定的,反之,不稳定。
上图中,升序排序前,红2在黑2的后面。经过方法①的排序之后,红2依然在黑2的后面,相对位置保持不变,所以认为算法①是稳定的;经过方法②排序后,红2跑到了黑2的前面,算法②不稳定。
2. 插入排序
2.1 思路
- [0,bound)表示已排区间,[bound,length-1]表示待排区间。
- 将待排区间的第一个元素 v 取出来,在已排区间找到合适的插入位置并插入。
- 以升序为例:注意,已排区间是已经排好的,里面的元素均符合升序的要求。所以在找 v 的插入位置时,从已排区间的后往前找更加方便。如果 v 大于已排区间的最后一个元素,那么将 v 放回原来的位置即可;如果 v 小于已排区间的最后一个元素,那么就需要将 v 插入到 最后一个元素的前面,数组的插入,意味着还需要挪动元素,将最后一个元素挪到下一个位置,再继续判断前一个元素和 v 的关系 ..... 直到找到那个合适的位置。
2.2 代码
public static void insertSort(int[] arr){
for(int bound=1;bound<arr.length;bound++){
//由于后面涉及到元素的挪动,可能会将bound位置的元素覆盖掉,所以将bound位置的元素取出保存起来
int v=arr[bound];
int cur=bound-1;
for(;cur>=0;cur--){
if(v<arr[cur]){
arr[cur+1]=arr[cur];
}else{
//找到合适的位置了
break;
}
}
//此时cur位置的元素小于v,所以将v插入到cur位置元素的后面
arr[cur+1]=v;
}
}
2.3 性能分析
稳定性: 稳定
2.4 结论
① 针对比较小的数组排序效率比较高。
② 如果数组本身已经比较有序,此时排序效率也比较高。
3. 希尔排序
基于插入排序得到的结论,发现针对比较小的数组排序效率比较高,那么能不能将一个数组分为一个一个的小数组再进行排序呢?数组本身已经比较有序,此时排序效率也比较高,那么我们能不能将这些小数组合并起来呢?此时便得到了一个相对比较有序的数组,继续重复上面的操作,逐渐将小数组分的更大,排序.....
这样排序的思想,就是希尔排序。
3.1 思路
- 给定一个分组系数 gap =3,表示分为3组,每一组的相邻元素的下标差值就是3
- 一般 gap 的值取 数组的长度 length /2,length/4,lengt