初级排序
数组排序实现的框架类
public class Example { public static void sort(Comparable[] a) {} private static boolean less(comparable v, Comparable w) { return v.compareTo(w) < 0; } private static void exch(Comparable[] a, int i, int j) { Comparable t = a[i]; a[i] = a[j]; a[j] = t; } private static void show(Comparable[] a) { //在单行中打印数组 for (int i = 0; i < a.length; i++) StdOut.print(a[i] + " "); StdOut.println(); } public static boolean isSorted(Comparable[] a) { //测试数组元素是否有序 for (int i = 1; i < a.length; i++) if (less(a[i], a[i-1])) return false; return true; } public static void main(String[] args) { //从标准输入读取字符串,将他们排序输出 String[] a = In.readStrings(); sort(a); assert isSorted(a); show(a); } }
选择排序:找到数组中最小的元素并交换到第一个位置,之后再剩下的元素中找到最小的再交换到第二个元素中,如此循环下去,总共需要大约N2/2次比较和N次交换。
public class Selection { public static void sort(Compareable[] a) { //将a[]按升序排序 int N - a.length; //数组长度 for (int i = 0; i < N; i++) { //将a[i]和a[i+1..N]中最小的元素交换 int min = 1; //最小元素的索引 for (int j = i + 1; j < N; j++) if (less(a[j], a[min])) min = j; exch(a, i, min); } } }
插入排序:将每一个元素插入到其他已经有序的元素中的适当位置。对于一个很多元素已经有序的数组来说这样排序会快得多。最好情况是N-1次比较和0次交换,最坏情况是N2/2次比较和交换,平均情况是N2/4次比较和交换。
public class Insertion { public static void sort(Comparable[] a) { //将a[]按升序排列 int N = a.length; for (int i = 1; i < N; i++) { //将a[i]输入到a[i-1]、a[i-2]...之中 for (int j = i; j > 0 && less(a[j], a[j-1]); j--) exch(a, j, j-1); } } }
希尔排序:代码量很小,且不需要使用额外的内存空间。将数组变为部分有序的,再进行插入排序,可以加快排序速度。
public class Shell { public static void sort(Compareable[] a) { //将a[]按升序排序 int N = a.length; //数组长度 int h = 1; while (h < N/3) h = 3*h + 1; //1, 4, 13, 40, ... while (h >= 1) { //将数组变为h有序 for (int i = h; i < N; i++) { //将a[i]插入到a[i-h], a[i-2*h], ... 之中 for (int j = i; j >= h && less(a[j], a[j-h]); j -= h) exch(a, j, j-h) } h = h/3; } } }