# 算法笔记－排序01:选择排序,插入排序,希尔排序

#### 实现两种初级的排序算法：

##### 完整代码
``````public class Selection {

public static void sort(Comparable[] a){
for (int i = 0; i < a.length; i++){
for (int j = i+1; j < a.length;j++){
if (less(a[j], a[i])) exchange(a,i,j);
}
}
show(a);
}

private static boolean less(Comparable v, Comparable w){
return v.compareTo(w) < 0;
}

private static void exchange(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++)
System.out.print(a[i]);
System.out.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;
}
}
``````
##### 分析

1.运行时间和输入无关：即使输入了一个已经有序的数组，这个算法依然会从头到尾的比较一遍，也就是说，没有利用到数组的初始状态。
2.数据移动较小：最多只进行N次交换。

##### 完整代码
``````public class Insertion {

public static void sort(Comparable[] a){
for (int i = 1; i < a.length; i++){
for (int j = i; j > 0 && less(a[j], a[j-1]);j--) exchange(a,j,j-1);
}
show(a);
}

private static boolean less(Comparable v, Comparable w){
return v.compareTo(w) < 0;
}

private static void exchange(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++)
System.out.print(a[i]);
System.out.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;
}
}
``````

#### 比较两种初级的排序算法：

##### 测试代码

1.用于计时的类

``````public class StopWatch {
private final long start;

public StopWatch(){
start = System.currentTimeMillis();
}

public double elapsedTime(){
long now = System.currentTimeMillis();
return (now-start)/1000.0;
}
}

``````
##### 用于比较两种排序算法运行时间的测试代码
``````public class Main {

public static void main(String[] args) {
String alg1 = args[0];
String alg2 = args[1];
int N = Integer.parseInt(args[2]);
int T = Integer.parseInt(args[3]);
double t1 = timeRandomInput(alg1,N,T);
double t2 = timeRandomInput(alg2,N,T);
System.out.println(alg1 + " : " + t1);
System.out.println(alg2 + " : " + t2);
}

public static double timeRandomInput(String alg, int N, int T){
double total = 0.0;
Double[] a = new Double[N];
for (int t = 0; t < T; t++){
for (int i = 0; i < N; i++) a[i] = Math.random();
total += time(alg,a);
}
}

public static double time(String alg, Double[] a){
StopWatch timer = new StopWatch();
if (alg.equals("Insertion")) Insertion.sort(a);
if (alg.equals("Selection")) Selection.sort(a);
if (alg.equals("Shell"))Shell.sort(a);
return timer.elapsedTime();

}
}
``````
##### 运行命令
``````% javac Insertion.java Main.java Selection.java StopWatch.java
% java Main Insertion Selection 10000 1000
``````

#### 一种改进：希尔排序

``````public class Shell {
public static void sort(Comparable[] a){
int N = a.length;
int h = 1;
while (h < N/3) h = 3*h + 1;
while (h >= 1){
for (int i = h; i < N; i++){
for (int j = i; j > h &&less(a[j], a[j-h]); j -= h)exchange(a,j,j-h);
}
h/=3;
}
}

private static boolean less(Comparable v, Comparable w){
return v.compareTo(w) < 0;
}

private static void exchange(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++)
System.out.print(a[i]);
System.out.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;
}
}

``````

##### 运行命令
``````% javac Shell.java
% java Main Insertion Shell 10000 1000
``````

Algorithm