1.选择排序
每次从未排序的元素中选择一个最小的,与未排序的第一个元素交换位置。
public static void selectSort(int[] a) {
int N = a.length;
for (int i = 0; i < N; i++) {//外循环从0到N-1,每次确定一个位置上应该放的元素
int min = i;
for (int j = i + 1; j < N; j++) {//内循环从未排序元素中找出最小的
if (less(a[j], a[min]) {
min = j;//迭代当前最小元素的索引,直到循环结束,最小元素确定
}
exch(a, i, min);//确定i上的元素
}
}
}
2.插入排序
每次从未处理的元素中取一个,在已处理的元素中找到合适的位置放入。
public static void insertSort(int[] a) {
int N = a.length;
for (int i = 1; i < N; i++) {//从第二个元素(i=1)开始,每次取一个移动到前面合适的位置
for (int j = i; j > 0 && less(a[j], a[j - 1]); j--) {
exch(a, j - 1, j);//如果当前的元素比它前面元素小,且当前元素位置不是0,说明j还没有找到合适的位置————那就交换
}
}
}
3.Shell排序
希尔排序基于插入排序。引入希尔排序的原因是:对于大规模乱序数组(如倒序)插入排序很慢,因为它只能交换相邻元素的位置,元素只能一点一点地从数组的一端移动到另一端。希尔排序为了加快速度改进了插入排序,交换不相邻的元素以对数组的局部进行排序,并最终用插入排序将局部有序(h有序数组)的数组排序。
对任意以1结尾的h序列(最后一次是插入排序),都能将数组排序。
常用的h序列(递增序列),用此递推公式产生: h = 1, h = 3 * h + 1
public static void shellSort(int[] a) {
int N = a.length;
int h = 1;
while (3 * h + 1 <= N) h = 3 * h + 1;//求递增序列初值
while (h >= 1) {//将数组变为h有序,直到h = 1
for (int i = h; i < N; i++) {//将插入排序的1都改为h
for ( int j = i; j >= h && less(a[j], a[j - h]); j -= h) {
exch(a, j - h, j);
}
}
h = (h - 1) / 3;
}
}
参考Sedgewick《算法》