各种排序算法的性能特点
算法 | 是否稳定 | 是否为原地排序 | 时间复杂度 | 空间复杂度 | 备注 |
---|---|---|---|---|---|
Selection | 否 | 是 | N^2 | 1 | |
Insertion | 是 | 是 | 介于N和N^2之间 | 1 | 取决于输入元素的排序情况 |
Shell | 否 | 是 | NlogN?N^6/5? | 1 | |
Merge | 是 | 否 | NlogN | N | |
Quick | 否 | 是 | NlogN | lgN | 运算效率由概率提供保证 |
Quick3way | 否 | 是 | 介于N与NlogN之间 | lgN | 运算效率由概率保证,同时也取决于输入元素的分布情况 |
Heap | 否 | 是 | NlogN | 1 |
选择排序
public class Selection {
// This class should not be instantiatd.
private Selection(){}
/**
* Rearranges the array in ascending order,using the natural order.
* @param a the array to be sorted
*/
public static void sort(Comparable[] a){
int N=a.length;
for(int i=0;i
插入排序
public class Insertion {
// This class should not be instantiatd.
private Insertion(){}
/**
* Rearranges the array in ascending order,using the natural order.
* @param a the array to be sorted
*/
public static void sort(Comparable[] a){
int N=a.length;
for(int i=1;i0&&less(a[j],a[j-1]);j--){
exch(a,j,j-1);
}
show(a);
}
}
// is v < w ?
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
// exchange a[i] and a[j]
private static void exch(Object[] a, int i, int j) {
Object swap = a[i];
a[i] = a[j];
a[j] = swap;
}
// print array to standard output
private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
StdOut.print(a[i]);
}
StdOut.println();
}
public static void main(String[] args) {
String[] test={"S","O","R","T","E","X","A","M","P","L","E"};
sort(test);
}
}
希尔排序
public class Shell {
// This class should not be instantiatd.
private Shell(){}
/**
* Rearranges the array in ascending order,using the natural order.
* @param a the array to be sorted
*/
public static void sort(Comparable[] a){
int N=a.length;
int h=1;
while(h=1){
for(int i=h;i=h&&less(a[j],a[j-h]);j-=h){
exch(a,j,j-h);
}
}
h=h/3;
show(a);
}
}
// is v < w ?
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
// exchange a[i] and a[j]
private static void exch(Object[] a, int i, int j) {
Object swap = a[i];
a[i] = a[j];
a[j] = swap;
}
// print array to standard output
private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
StdOut.print(a[i]);
}
StdOut.println();
}
public static void main(String[] args) {
String[] test={"S","H","E","L","L","S","O","R","T","E","X","A","M","P","L","E"};
sort(test);
}
}
归并排序
本地归并排序
public class Merge {
// This class should not be instantiated.
private Merge() { }
// stably merge a[lo .. mid] with a[mid+1 .. hi] using aux[lo .. hi]
public static void merge(Comparable[] a, Comparable[] aux, int lo, int mid, int hi) {
for (int k = lo; k <= hi; k++) aux[k] = a[k];
int i = lo, j = mid+1;
for (int k = lo; k <= hi; k++) {
if (i > mid) a[k] = aux[j++];
else if (j > hi) a[k] = aux[i++];
else if (less(aux[j], aux[i])) a[k] = aux[j++];
else a[k] = aux[i++];
}
}
public static void sort(Comparable[] a){
Comparable[] aux = new Comparable[a.length];
sort(a,aux,0,a.length-1);
}
public static void sort(Comparable[] a,Comparable[] aux,int lo,int hi){
if(hi<=lo)return;
int mid=lo+(hi-lo)/2;
sort(a,aux,lo,mid);
sort(a,aux,mid+1,hi);
merge(a,aux,lo,mid,hi);
}
// is v < w ?
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
// exchange a[i] and a[j]
private static void exch(Object[] a, int i, int j) {
Object swap = a[i];
a[i] = a[j];
a[j] = swap;
}
// print array to standard output
private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
StdOut.print(a[i]);
}
StdOut.println();
}
public static void main(String[] args) {
String[] test={"E","E","G","M","R","A","C","E","R","T"};
// String[] test={"M","E","R","G","E","S","O","R","T","E","X","A","M","P","L","E"};
sort(test);
show(test);
}
}
自底向上的归并排序
public class MergeBU {
private static Comparable[] aux;
public static void merge(Comparable[] a, Comparable[] aux, int lo, int mid, int hi) {
for (int k = lo; k <= hi; k++) aux[k] = a[k];
int i = lo, j = mid + 1;
for (int k = lo; k <= hi; k++)
if (i > mid) a[k] = aux[j++];
else if (j > hi) a[k] = aux[i++];
else if (less(aux[j],aux[i])) a[k] = aux[j++];
else a[k] = aux[i++];
}
public static void sort(Comparable[] a) {
Comparable[] aux = new Comparable[a.length];
int N = a.length;
for (int sz = 1; sz < N; sz = sz + sz) {
for (int lo = 0; lo < N - sz; lo += sz + sz) {
merge(a, aux,lo, lo + sz - 1, Math.min(lo + sz + sz - 1, N - 1));
}
}
}
// is v < w ?
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
// exchange a[i] and a[j]
private static void exch(Object[] a, int i, int j) {
Object swap = a[i];
a[i] = a[j];
a[j] = swap;
}
// print array to standard output
private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
StdOut.print(a[i]);
}
StdOut.println();
}
public static void main(String[] args) {
String[] test = {"M", "E", "R", "G", "E", "S", "O", "R", "T", "E", "X", "A", "M", "P", "L", "E"};
sort(test);
show(test);
}
}
快速排序
public class Quick {
//This class should not be instantiatd
private Quick() {
}
public static void sort(Comparable[] a) {
sort(a, 0, a.length - 1);
}
private static void sort(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);
}
private static int partition(Comparable[] a, int lo, int 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;
}
// is v < w ?
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
// exchange a[i] and a[j]
private static void exch(Object[] a, int i, int j) {
Object swap = a[i];
a[i] = a[j];
a[j] = swap;
}
// print array to standard output
private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
StdOut.print(a[i]);
}
StdOut.println();
}
public static void main(String[] args) {
String[] test = {"K", "R", "A", "T", "E", "L", "E", "P", "U", "I", "M", "Q", "C", "X", "O", "S"};
sort(test);
}
}
三向切分的快速排序
public class Quick3way {
private Quick3way() {}
private static void sort(Comparable[] a) {
sort(a, 0, a.length - 1);
}
private static void sort(Comparable[] a, int lo, int hi) {
if (hi <= lo) return;
int lt = lo, i = lo + 1, gt = hi;
Comparable v = a[lo];
while (i <= gt) {
int cmp = a[i].compareTo(v);
if (cmp < 0) exch(a, lt++, i++);
else if (cmp > 0) exch(a, i, gt--);
else i++;
}
sort(a, lo, lt - 1);
sort(a,gt+1,hi);
}
// exchange a[i] and a[j]
private static void exch(Object[] a, int i, int j) {
Object swap = a[i];
a[i] = a[j];
a[j] = swap;
}
// print array to standard output
private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
StdOut.print(a[i]);
}
StdOut.println();
}
public static void main(String[] args) {
String[] test = {"R", "B", "W", "W", "R", "W", "B", "R", "R", "W", "B", "R"};
// Integer[] test={9,8,7,6,5,7,7,4,3,4,2,4,1};
sort(test);
show(test);
}
}
堆排序
public class Heap {
private static void sink(Comparable[] a, int k, int N) {
while (2 * k <= N) {
int j = 2 * k;
if (j < N && less(a, j, j + 1)) j++;
if (!less(a, k, j)) break;
exch(a, k, j);
k = j;
}
}
private static boolean less(Comparable[] a, int i, int j) {
return a[i-1].compareTo(a[j-1]) < 0;
}
private static void exch(Comparable[] a, int i, int j) {
Comparable t = a[i-1];
a[i-1] = a[j-1];
a[j-1] = t;
}
public static void sort(Comparable[] a) {
int N = a.length;
for (int k = N / 2; k >= 1; k--)
sink(a, k, N);
while (N > 1) {
exch(a, 1, N--);
sink(a, 1, N);
}
}
// print array to standard output
private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
StdOut.print(a[i]);
}
StdOut.println();
}
public static void main(String[] args) {
String[] test = {"S", "O", "R", "T", "E", "X", "A", "M", "P", "L", "E"};
sort(test);
show(test);
}
}
~~
缺少每个算法的引述,算法实现过程中未做数组扩展、未做数组越界判断、未实现Iterator接口等,这些等补全之后在更新。
参考博客
七大排序算法性能的分析