常用排序算法

import java.util.Random;

public class MySort {

    private static void quickSort(int[] arr, int left, int right) {
        //進行判斷,如果左邊索引比右邊索引大,是不合法的,直接使用return結束這個方式
        if (left > right) {
            return;
        }
        //定義變量保存基準數
        int base = arr[left];
        //定義變量i,指向最左邊
        int i = left;
        //同理,定義變量j,指向最右邊
        int j = right;

        while (i != j) {
            //由j從右往左檢索比基準數小的,如果檢索到比基準數小的就停下
            //如果檢索比基準數大的或者相等的,就繼續檢索
            while (arr[j] >= base && i < j) {
                //j從右往左移動
                j--;
            }
            while (arr[i] <= base && i < j) {
                //i從左往右移動
                i++;
            }
            //運行到這裏表示: i停下了,j也停下了,然後開始交換彼此位置上的元素
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
        //如果上面的while循環的條件不成立,會跳出這個循環,往下執行
        //如果這個條件不成立說明了i和j相遇了
//        如果i和j相遇了,就交換基準數這個元素和相遇位置的元素,
        //把相遇位置的元素賦值給基準數這個位置的元素
        arr[left] = arr[i];
        arr[i] = base;

        //基準數在這裏就歸爲了,左邊的數都比它小,右邊的數都比它大
        //排基準數的左邊
        quickSort(arr, left, i - 1);
        //排基準數的右邊
        quickSort(arr, j + 1, right);
    }

    /**
     *  * <pre>
     *  * 二路歸併
     *  * 原理:將兩個有序表合併和一個有序表
     *  * </pre>
     *  *
     *  * @param a
     *  * @param s
     *  * 第一個有序表的起始下標
     *  * @param m
     *  * 第二個有序表的起始下標
     *  * @param t
     *  * 第二個有序表的結束下標
     *  *
     */
    private static void merge(int[] a, int s, int m, int t) {
        int[] tmp = new int[t - s + 1];
        int i = s, j = m, k = 0;
        while (i < m && j <= t) {
            if (a[i] <= a[j]) {
                tmp[k] = a[i];
                k++;
                i++;
            } else {
                tmp[k] = a[j];
                j++;
                k++;
            }
        }
        while (i < m) {
            tmp[k] = a[i];
            i++;
            k++;
        }
        while (j <= t) {
            tmp[k] = a[j];
            j++;
            k++;
        }
        System.arraycopy(tmp, 0, a, s, tmp.length);
    }

    /**
     *  *
     *  * @param a
     *  * @param s
     *  * @param len
     *  * 每次歸併的有序集合的長度
     */
    private static void mergeSort(int[] a, int len) {
        int size = a.length;
        int mid = size / (len << 1);
        int c = size & ((len << 1) - 1);
        // -------歸併到只剩一個有序集合的時候結束算法-------//
        if (mid == 0) {
            return;
        }
        // ------進行一趟歸併排序-------//
        for (int i = 0; i < mid; ++i) {
            int s = i * 2 * len;
            merge(a, s, s + len, (len << 1) + s - 1);
        }
        // -------將剩下的數和倒數一個有序集合歸併-------//
        if (c != 0) {
            merge(a, size - c - 2 * len, size - c, size - 1);
        }
        // -------遞歸執行下一趟歸併排序------//
        mergeSort(a, 2 * len);
    }

    /**
     * 希爾排序
     *
     * @param array
     * @return
     */
    private static int[] shellSort(int[] array) {
        int len = array.length;
        int temp, gap = len / 2;
        while (gap > 0) {
            for (int i = gap; i < len; i++) {
                temp = array[i];
                int preIndex = i - gap;
                while (preIndex >= 0 && array[preIndex] > temp) {
                    array[preIndex + gap] = array[preIndex];
                    preIndex -= gap;
                }
                array[preIndex + gap] = temp;
            }
            gap /= 2;
        }
        return array;
    }

    /**
     * 插入排序
     *
     * @param array
     * @return
     */
    private static int[] insertionSort(int[] array) {
        if (array.length == 0) {
            return array;
        }
        int current;
        for (int i = 0; i < array.length - 1; i++) {
            //取第二個元素的值
            current = array[i + 1];
            //前一個下標
            int preIndex = i;

            while (preIndex >= 0 && current < array[preIndex]) {
                array[preIndex + 1] = array[preIndex];
                preIndex--;
            }

            array[preIndex + 1] = current;
        }
        return array;
    }

    /**
     * 選擇排序
     *
     * @param array
     * @return
     */
    private static int[] selectionSort(int[] array) {
        if (array.length == 0) {
            return array;
        }
        for (int i = 0; i < array.length; i++) {
            int minIndex = i;
            for (int j = i + 1; j < array.length; j++) {
                //找到最小的數
                if (array[j] < array[minIndex]) {
                    //將最小數的索引保存
                    minIndex = j;
                }
            }
            //調換最小值順序
            int temp = array[minIndex];
            array[minIndex] = array[i];
            array[i] = temp;
        }
        return array;
    }

    /**
     * 冒泡排序
     *
     * @param array
     * @return
     */
    private static int[] bubbleSort(int[] array) {
        if (array.length == 0) {
            return array;
        }
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array.length - 1 - i; j++) {
                if (array[j + 1] < array[j]) {
                    int temp = array[j + 1];
                    array[j + 1] = array[j];
                    array[j] = temp;
                }
            }
        }
        return array;
    }


    public static void main(String[] args) {
        int[] arr = new int[10000];
        Random r = new Random();
        //給數組元素賦值
        for (int i = 0; i < arr.length; i++) {
            //生成隨機數
            int num = r.nextInt();
            arr[i] = num;
        }

        long start = System.currentTimeMillis();

        //254
//        bubbleSort(arr);

        //94
//        selectionSort(arr);

        //37
//        insertionSort(arr);

        //6
//        shellSort(arr);
        //5
//        mergeSort(arr, 1);

//        1
        quickSort(arr, 0, arr.length - 1);

        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }
}

待添加堆排序、基數排序、計數排序等。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章