每个算法都会用到的通用方法:
//如果元素v<w返回true,否则返回false
public boolean less(Comparable v,Comparable w){
return v.compareTo(w) <0;
}
//交换数组a的元素i和j
public void exch(Comparable[] a,int i,int j){
Comparable tComparable=a[i]; a[i]=a[j]; a[j]=tComparable;
}
1.选择排序:找出数组中最小的那个元素,将它和数组的第一个元素交换(如果最小元素就是第一个则和本身交换)。然后在从剩下的元素中找出最小的元素,和二个交换。对于长度为N的数组,选择排序大约需要N^2/2次比较和N次交换。它的运行时间和输入无关。
public void sort(Comparable[] 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);
}
}
2.插入排序:假设数组a[]需要排序,插入排序会将a[i]与a[0]到a[i-1]中比它小的元素一次有序地交换。在索引i向右移动地过程中,左侧元素总是有序地,当i到达数组右边时,排序久完成了。插入排序需要交换操作和数组中倒置地数量相同,需要地比较次数大于等于倒置地数量,小于等于倒置数量加数组大小在减一。
public void sort(Comparable[] a){
int N=a.length;
for (int i = 1; i < N; i++) {
//将a[i]插入到以前的元素中
for(int j=i;j>0&&less(a[j], a[j-1]);j--){
exch(a, j, j-1);
}
}
}
3.希尔排序:希尔排序地思想是使数组中任意间隔为h地元素都是有序地。这样地数组被称为h有序数组。假设h的初始值为3 。int[] a={7,6,5,4,3,2,1} 我们首先保证数组里a[0] ,a[3],a[6]相对整个数组有序 ,将这三个元素按插入排序后数组为{1,6,5,4,3,2,7}。然后在h=2 h=1,最后整个数组都会变成有序。算法如下:
public void sort(Comparable[] a){
//将a[]按升序排列
int N=a.length;
int h=1;
while(h<N/3) h=3*h+1;
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;
}
}
4.归并排序: 实现归并排序简单的方法就是将两个不同的有序数组归并到第三个数组中。
//归并用的堵住数组
private Comparable[] aux;
public void sort1(Comparable[] a){
aux=new Comparable[a.length];
sort1(a,0,a.length-1);
}
private void sort1(Comparable[] a,int lo,int hi){
if(hi<lo) return;
int mid=lo+(hi-lo)/2;
sort1(a,lo,mid); //左半部分排序
sort1(a, mid+1, hi);//右半部份排序
merage(a, lo, mid, hi);
}
/**
* 归并排序的抽象方法 ,将a[lo..mig]和a[mid+1..hi}归并成一个有序数组,并将结果存放在a[lo..hi]中
* @param a 数组a
* @param lo 第一个子数组起始
* @param mid 第一个子数组结束
* @param hi 第二个子数组结束
*/
public void merage(Comparable[] a,int lo,int mid,int hi){
int i=lo,j=mid+1;
for(int k=lo; k<=hi;k++){//复制数组
aux[k]=a[k];
}
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++];
}
}
参考书:算法