冒泡排序:将数组中的最大或最小值往一端移动,两层循环,每次比较和移动一个数字,比较和交换复杂度O(),可以理解为贪心算法。
public static void sort(int[] a) {
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a.length - i - 1; j++) {
if (a[j] > a[j + 1]) SortUtils.swap(a, j, j + 1);
}
}
}
插入排序:左边是有序的,当外层循环到最右边时排序结束,比较和交换复杂度O()。
public static void sort(int[] a) {
for (int i = 1; i < a.length; i++) {
for (int j = i; j > 0 && a[j] < a[j - 1]; j--) {
SortUtils.swap(a, j, j - 1);
}
}
}
选折排序:左边是有序的,每次从剩余的选一个最大或最小的排到有序的后边,比较复杂度O(),交换O(n)。
public static void sort(int[] a) {
for (int i = 0; i < a.length; i++) {
int min = i;
for (int j = i + 1; j < a.length; j++) {
if (a[min] > a[j]) min = j;
}
SortUtils.swap(a, min, i);
}
}
希尔排序:可以看出上面几种排序算法所要的比较和交换次数都比较多,希尔排序是在插入排序基础上的一种优化,插入排序每次和前一个数比较和交换,希尔排序先比较和交换间隔大的数字,再逐渐缩小间隔排序,这一点变动,使得复杂度从平方级降到线性级。
public static void sort(int[] a) {
int h = 1;
while (h < a.length / 3) h = h * 3 + 1;
while (h >= 1) {
for (int i=h;i<a.length;i++){
for (int j = i; j >= h && a[j] < a[j - h]; j -= h) {
SortUtils.swap(a, j, j - h);
}
}
h /= 3;
}
}