前言:
之前介绍了选择,插入以及它们的优化,发下在几乎有序的情况下,插入排序的高效性~
一、冒泡排序
- 数组中第一个元素开始两两比较,前者比后者大就交换一下
- 第一趟的最大值已经排上去后,那么接着从第一个元素开始比较到n-1个数,以此类推~
public static void sort(Comparable[] arr){
int n = arr.length;
// n-1和n都可以,因为下面的j还会判断一次
for(int i = 0; i < n-1; i ++){
for(int j = i + 1; j < n; j ++){
if(arr[i].compareTo(arr[j]) > 0)
swap(arr, i, j);
}
}
}
1.1 优化
每一趟的Sort都将最大值放在了后面,所以之后的每一趟都可以不用再考虑了,尽管比较简单,但是时间上还有一点点的提高
public static void sort(Comparable[] arr){
int n = arr.length;
for(int i = 0; i < n-1; i ++){
for(int j = i + 1; j < n; j ++){
if(arr[i].compareTo(arr[j]) > 0)
swap(arr, i, j);
}
}
}
对4w个无序的数组进行测试,可知稍微有一点点的提高~
二、 希尔排序
这是插入排序衍生的,插入排序中每个元素和之前1个元素比较,而希尔是每个元素和t个元素比较,然后t慢慢缩小成1,整个整数从无序慢慢到几乎有序,那么到最后近乎有序,t为1的话就特别快了~ 时间复杂度为O(n^(3/2))
public static void sort(Comparable[] arr){
int n = arr.length;
//步长为3
int h = 1;
while(h < n/3) h = 3 * h + 1;
while(h >= 1){
for(int i = h; i < n; i ++){
// 对 arr[i], arr[i-h], arr[i-2*h], arr[i-3*h]... 使用插入排序
Comparable e = arr[i];
int j = i;
for( ; j >= h && e.compareTo(arr[j-h]) < 0; j -=h ){
arr[j] = arr[j-h]; //swap的优化写法
}
arr[j] = e;
}
h /= 3;
}
}
四、总结:
- 希尔排序:插入的改进版,肯定是在这4种里最好的~
- 选择排序:简单但是两重循环每次都要完成~效率慢
- 插入排序:复杂度也是O(n^2),但是数组在几乎有序的情况下,效率甚至比 O(n* logn)的还要高,有着重要的实际意义
- 冒泡排序:有许多的换操作,平庸~
附一张O(n^2)排序算法跑数据的图: