排序算法类的模板
public class Example{
public staic void sort(Comparable[] a){
//coding here...
}
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++){
System.out.print(a[i]+" ");
}
}
public static boolean isSorted(Comparable[] a){
//测试数组元素是否有序
for(int i = 0;i<a.length;i++){
if(less(a[i],a[i-1])){
return false;
}
}
return true;
}
}
一、冒泡排序
基本思想:两两比较待排序记录的关键字,发现两个记录的次序相反时即进行交换,直到没有反序的记录为止。
public class Bubble{
public static void sort(int[] source){
for(int i = source.length-1;i>0;i--){
for(int j=0;j<i;j++){
if(less(source[j+1]),source[j]){
exch(source,j,j+1);
}
}
}
}
}
二、选择排序
基本思想:选择排序是一种简单直观的排序算法。它首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,放到排序序列末尾。以此类推,知道所有的元素均排序完毕。
public class selection{
public static void sort(int[]srouce){
for(int i =0;i<source.length;i++){
for(int j =i+1;j<source.length;j++){
if(less(source[j],source[i])){
exch(source,i,j);
}
}
}
}
}
三、插入排序
基本思想:
1. 从第一元素开始,该元素可以认为已经被排序。
2. 取出下一个元素,在已经排序的元素序列中从后向前扫描。
3. 如果该元素(已排序)大于新元素,则该元素移到下一位置。
4. 重复步骤3,直到找到已排序的元素小于或等于新元素的位置
5. 将新元素插入到该位置中
6. 重复步骤2
public class Insertion{
public static void sort(int[]sort){
for(int i=1;i<source.length;i++){
for(int j =i;(j>0)&&less(source[j],source[j-1]);j--){
exch(source,j,j-1);
}
}
}
}
四、快速排序
快速排序是一种分治的排序算法。它将一个数组分成两个子数组,将两部分独立地排序。在快速排序中,切分的位置取决于数组的内容。
public class 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);//将左半部分a[lo..j-1]排序
sort(a,j+1,hi);//将右半部分a[j+1..hi]排序
}
private static int partition(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 == ho) break;
if(i >= j) break;
exch(i,j);
}
exch(a,lo,j); //将v = a[j]放入正确的位置
return j;//a[lo..j-1]<=a[j]<=a[j+1..hi]达成
}
}
改进算法:三向切分的快速排序,三向切分能够将和切分元素相等的元素归位,这样它们就不会被包含在递归调用处理的子数组之中了。对于大量重复元素的数组,这种方法比标准的快速排序的效率高得多。
public class Quick3way{
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++;
} //现在a[lo..lt-1] <v =a[lt..gt] < a[gt+1..hi]成立
sort(a,i,lt-1);
sort(a,gt+1,hi);
}
}