抉择排序

思路

  1. <font face=黑体>在须要排序的数据域中,先把最小的拿进去,放在适合的地位;
  2. <font face=黑体>剩下的,再把最小的拿进去,放在适合的地位;
  3. <font face=黑体>剩下的,再把最小的拿进去,放在适合的地位;
  4. <font face=黑体>...

<font face=黑体 color = red>每次抉择还没有解决的元素里最小的元素。

留神

<font face=黑体>抉择排序是能够原地排序的,即不须要开拓额定的空间。

代码实现

public class SelectionSort {    private SelectionSort() {    }    /**     * 抉择排序1(从头到尾遍历)     * @param arr     * @param <E>     */    public static <E extends Comparable<E>> void sort(E[] arr) {        for (int i = 0; i < arr.length; i++) {            // 抉择 arr[i...n) 中的最小值的索引            int minIndex = i;            for (int j = i + 1; j < arr.length; j++) {                if (arr[j].compareTo(arr[minIndex]) < 0) {                    minIndex = j;                }            }            swap(arr, i, minIndex);        }    }    /**     * 抉择排序2(从尾到头遍历)     * @param arr     * @param <E>     */    public static <E extends Comparable<E>> void sort1(E[] arr) {        for (int i = arr.length - 1; i >= 0 ; i--) {            int maxIndex = i;            for (int j = i; j >= 0 ; j--) {                if (arr[j].compareTo(arr[maxIndex]) > 0) {                    swap(arr, i, maxIndex);                }            }        }    }    // 替换    private static <E> void swap(E[] arr, int i, int j) {        E temp = arr[i];        arr[i] = arr[j];        arr[j] = temp;    }    public static void main(String[] args) {        int[] dataSize = {10000, 100000};        for (int n : dataSize) {            Integer[] arr = ArrayGenerator.generateRandomArray(n, n);            SortingHelper.sortTest("SelectionSort", arr);        }    }}

运行后果

<font face=黑体>抉择排序是一个工夫复杂度为 O(n^2) 的排序算法,所以当 n 增大 10 倍的时候,排序所需工夫差不多差不多减少了 100 倍,运行后果如下所示:


_
<font face=黑体>以下是上述代码中用到的两个类:

ArrayGenerator

<font face=黑体>作用次要是生成随机的数组,具体如下所示:

public class ArrayGenerator {    private ArrayGenerator() {    }    /**     * 生成长度为 n 的有序数组     *     * @param n     * @return     */    public static Integer[] generateOrderedArray(int n) {        Integer[] arr = new Integer[n];        for (int i = 0; i < arr.length; i++) {            arr[i] = i;        }        return arr;    }    /**     * 生成长度为 n 的随机数组,每个数字的范畴是[0, bound)     *     * @param n     * @param bound     * @return     */    public static Integer[] generateRandomArray(int n, int bound) {        Integer[] arr = new Integer[n];        Random rnd = new Random();        for (int i = 0; i < n; i++) {            arr[i] = rnd.nextInt(bound);        }        return arr;    }}

SortingHelper

<font face=黑体>作用次要是测试各种排序算法的性能,具体如下所示:

public class SortingHelper {    private SortingHelper() {    }    /**     * 判断一个数组是否有序     *     * @param arr     * @param <E>     * @return     */    public static <E extends Comparable<E>> boolean isSorted(E[] arr) {        for (int i = 1; i < arr.length; i++) {            if (arr[i - 1].compareTo(arr[i]) > 0) {                return false;            }        }        return true;    }    /**     * 测试排序算法的性能     *     * @param sortName     * @param arr     * @param <E>     */    public static <E extends Comparable<E>> void sortTest(String sortName, E[] arr) {        long startTime = System.nanoTime();        if (sortName.equals("SelectionSort")) {            SelectionSort.sort(arr);        } else if (sortName.equals("InsertionSort")) {            InsertionSort.sort(arr);        } else if (sortName.equals("InsertionSort2")) {            InsertionSort.sort2(arr);        }        long endTime = System.nanoTime();        double time = (endTime - startTime) / 1000000000.0;        if (!SortingHelper.isSorted(arr)) {            throw new RuntimeException(sortName + " failed");        }        System.out.println(String.format("%s , n = %d : %f s", sortName, arr.length, time));    }}