publicclassSelection { publicstaticvoidsort(Comparable[] a) { //将a[]按升序排列 int N = a.length; for (int i = 0;i < N;i++) { int min = i; for (int j = i + 1;j < N;j++) if (less(a[j], a[min])) min = j; exch(a, i, min); } } //less(),exch(),isSorted()和main()方法见通用模板 }
对于长度为$N$的数组,选择排序需要大约$N^{2}/2$次比较和$N$次交换
插入排序
1 2 3 4 5 6 7 8 9 10 11 12 13
publicclassInsertion_1 { publicstaticvoidsort(Comparable[] a) { //将a[]按升序排列 int N = a.length; for (int i = 1; i < N; i++) { //将a[i]插入到a[i-1],a[i-2],a[i-3]...之中 for (int j = i; j > 0 && less(a[j], a[j - 1]); j--) exch(a, j, j - 1); } } //less(),exch(),isSorted()和main()方法见通用模板 }
privatestaticvoidsort(Comparable[] a, int lo, int hi) { if (hi <= lo) return; int j = partition(a, lo, hi);//切分 sort(a, lo, j - 1); sort(a, j + 1, hi); }
privatestaticintpartition(Comparable[] a, int lo, int hi) { //将数组切分为a[lo...i-1],a[i],a[i+1...hi] int i = lo, j = hi + 1; Comparable v = a[lo]; //切分元素 while (true) { while (less(a[++i], v)) if (i == hi) break; while (less(v, a[--j])) if (j == lo) break; if (i >= j) break; exch(a, i, j); } exch(a, lo, j); return j; } //less(),exch(),isSorted()和main()方法见通用模板 }
将长度为$N$的无重复数组排序,快速排序平均需要~$2NlnN$次比较(以及$1/6$的交换)
算法改进
A.切换到插入排序
在排序小数组时切换到插入排序,如将$sort()$中的语句
1
if (hi <= lo) return;
替换为
1
if (hi <= lo + M) { Insertion.sort(a, lo, hi); return; }
publicstaticvoidsort(Comparable[] pq) { int n = pq.length;
for (int k = n / 2; k >= 1; k--) sink(pq, k, n);
int k = n; while (k > 1) { exch(pq, 1, k--); sink(pq, 1, k); } }
privatestaticvoidsink(Comparable[] pq, int k, int n) { while (2 * k <= n) { int j = 2 * k; if (j < n && less(pq, j, j + 1)) j++; if (!less(pq, k, j)) break; exch(pq, k, j); k = j; } }
privatestaticbooleanless(Comparable[] pq, int i, int j) { return pq[i - 1].compareTo(pq[j - 1]) < 0; }
privatestaticvoidexch(Object[] pq, int i, int j) { Object swap = pq[i - 1]; pq[i - 1] = pq[j - 1]; pq[j - 1] = swap; }
privatestaticvoidshow(Comparable[] a) { for (int i = 0; i < a.length; i++) { StdOut.println(a[i]); } }