Fork me on GitHub

选择排序,插入排序以及希尔排序

1. 选择排序

  1. 首先,找到数组中最小的那个元素;
  2. 将它与数组中的第一个元素交换位置;
  3. 在剩下的数组中找到最小的元素,和数组的第二个元素交换位置,如此循环往复;
public class Selection{

    // 将数组a按升序排列
    public static 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);
            }
        }
    }

    // 数组两个元素比较
    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;
    }

    // 测试数组是否有序
    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;
    }
}

2. 插入排序

  • 当前索引左边的所有元素都是有序的;
  • 更小的元素插入之前,需要将比它的元素右移一位;
public class Insertion{
    public static void sort(Comparable[] 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);
            }
        }
    }
}

3. 希尔排序

  • 基于插入排序;
  • 插入排序只会交换相邻元素;希尔排序交换不相邻元素,以及对数组局部排序;
  • 希尔排序的思想是使数组中任意间隔为h的元素都是有序的;
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){
            // 将数组变为h有序
            for(int i = h; i < N; i++){
                for(int j = i; j >= h && less(a[j], a[j - h]); j -= h){
                    exch(a, j, j-h);
                }
            }
            h = h/3;
        }
    }
}

参考资料:

posted @ 2018-08-25 23:31  小a的软件思考  阅读(273)  评论(0编辑  收藏  举报