常用排序实现

1.选择排序

一种最简单的排序算法是这样的:首先,找到数组中的最小的元素,其次,将他和第一个元素交换位置。再次,在剩下的元素中找到最小的元素,将他换到第二个元素的位置。如此往复,这种方法就是选择排序,一直不断不断地选择剩余元素中的最小者。选择排序的时间复杂度为n²。
实现:

public static void sort(Comparable[] a){
       int n = a.length;
       for(int i = 0; i < n; i++){
           //将a[i]和a[+1]中最小的元素进行交换
           int min = i;
           for(int j = i + 1; j < n; j++){
               if(a[j].compareTo(a[min]) > 0){
                   min = j;
               }
               Comparable t = a[i];
               a[i] = a[min];
               a[min] = t;
           }
       }
   }

2.插入排序

将一个数字插入一个已经有序的数组中,并且依然保持有序,这就是插入排序。插入排序的时间复杂度在最坏的情况下,时间时间复杂度为n²,最好的情况下的时间复杂度则为n。

public static void sort(Comparable[] a){
        int n = a.length;
        for(int i = 0; i < n; i++){
            for(int j = i; j > 0 && a[j].compareTo(a[j - 1]) > 0; j--){
                Comparable t = a[j];
                a[j] = a[j - 1];
                a[j - 1] = t;
            }
        }
    }

希尔排序

希尔排序是基于插入排序的一种排序算法。对于大规模的乱序数组插入排序会很慢,因为它只会交换相邻的元素,因此元素只能一点点的从一端移动到另一端。希尔排序为了加速简单地改进了插入排序。
希尔排序的思想是使数组中的任意间隔为h的元素都是有序的。对于没一段间隔h,用插入排序的将h个子数组独立。每次每个元素的移动有插入排序的1变为h。希尔排序的高效在于它权衡了子数组规模和有序性。

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 && a[j].compareTo(a[j - h]) > 0; j -= h){
                    Comparable t = a[j];
                    a[j] = a[j - h];
                    a[j - h] = t;
                }
            }
            h = h / 3;
        }
    }

归并排序

归并排序是基于归并这个操作,即将两个有序的数组归并成一个更大的有序数组。归并排序的时间复杂度为NlgN。

public class MergeSort {

    private static Comparable[] aux;

    public static void sort(Comparable[] a){
        aux = new Comparable[a.length];
        sort(a, 0, a.length - 1);
    }

    private static void sort(Comparable[] a, int start, int end){
        //将数组a[start..end]排序
        if(end <= start)
            return;
        int mid = start + (end - start) / 2;
        sort(a, start, mid);
        sort(a, mid + 1, end);
        merge(a, start, mid, end);
    }

    public static void merge(Comparable[] a, int start, int mid, int end){
        //归并
        int i = start;
        int j = mid + 1;
        //保存副本
        for(int k = start; k <= end; k++)
            aux[k] = a[k];

        for(int k = start; k <= end; k++){
            if(i > mid){
                a[k] = aux[j++];
            } else if(j > end){
                a[k] = aux[i++];
            } else if(aux[j].compareTo(aux[i]) > 0){
                a[k] = aux[j++];
            } else {
                a[k] = aux[i++];
            }
        }
    }
}

快速排序

快速是基于分治的排序算法。它将一个数组分成两个数组,将两部分独立的排序。快速排序和归并排序是互补的:归并排序将数组分成两个子数组分别排序,并将有序的子数组归并以将整个数组排序;而快速排序是当成两个子数组都有序时整个数组也就自然有序了。归并排序递归调用发生在处理整个数组之前,一个数组被等分为两半;快速排序递归发生在处理整个数组之后,切分的位置取决于数组的内容。

public class QuickSort {

    public static void sort(Comparable[] a){
        sort(a, 0, a.length - 1);
    }

    private static void sort(Comparable[] a, int start, int end){
        if(end <= start)
            return;
        int j = partition(a, start, end);
        sort(a, start, j - 1);
        sort(a, j + 1, end);
    }

    private static int partition(Comparable[] a, int start, int end){
        int i = start;
        int j = end + 1;
        Comparable v = a[start];
        while (true){
            while (a[++i].compareTo(v) > 0)
                if(i == end)
                    break;
            while (v.compareTo(a[--j]) > 0)
                if(j == start)
                    break;
            if(i >= j)
                break;
            Comparable t = a[i];
            a[i] = a[j];
            a[j] = t;
        }
        Comparable t = a[start];
        a[start] = a[j];
        a[j] = t;
        return j;
    }

    public static void main(String[] args) {
        Integer[] a = new Integer[]{4,9,2,8};
        sort(a);
        for(Integer b : a){
            System.out.println(b);
        }

    }
}

你可能感兴趣的:(常用排序实现)