Java实现七大排序

  ↵

图片来自

import com.sun.scenario.effect.Merge;

public class Sort {

    private static void swap(int arr[], int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

    // 1. 冒泡排序
    // 时间复杂度为 N^2
    // 空间复杂度O(1)
    // 稳定排序
    public static void bubbleSort(int[] arr, int len) {
        /**
         * 1>相邻两数进行比较,比较一遍后,最后一个数最大。
         * 2>进行n-1遍后,排列有序
         */
        for (int i = 0; i < len; i++) {
            boolean flag = true;
            for (int j = 0; j < len - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) { //相邻两数进行比较,若前大于后,交换俩数
                    swap(arr, j, j + 1);
                    flag = false;
                }
            }
            if (flag)
                continue;
        }
    }


    /**
     * 2. 插入排序:将数据插入前面已经排好序的队列中
     * 平均时间复杂度为 N^2
     * 空间复杂度O(1)
     * 稳定排序
     *
     * @param arr
     * @param length
     */
    public static void insertSort(int[] arr, int length) {
        int i, j;
        for (i = 1; i < length; i++) {
            int tmp = arr[i];
            for (j = i; j > 0 && arr[j - 1] > tmp; j--) {
                arr[j] = arr[j - 1];
            }
            arr[j] = tmp;
        }
    }


    /**
     * 3. 选择排序:
     * 每一趟从待排序的数据元素中选择最小(或最大)的一个元素作为首元素,
     * 直到所有元素排完为止。
     */
    public static void selectSort(int[] arr, int len) {
        for (int i = 0; i < len; i++) {
            int min = i;
            for (int j = i + 1; j < len; j++) {
                if (arr[j] < arr[min]) {
                    min = j;
                }
            }
            if (min != i)// 若min发生改变,进行交换
                swap(arr, i, min);
        }
    }


    /**
     * 4. 希尔排序:改进版的插入排序
     * 步长由长到短分组,进行排序,直到步长为1为止
     *
     * @param arr
     * @param len
     */
    public static void shellSort(int[] arr, int len) {
        for (int gap = len / 2; gap > 0; gap /= 2) {// 间隔量gap
            // 下面相当于插入排序(插入排序相当于是间隔量为1的希尔排序)
            for (int i = gap; i < len; i++) {
                int tmp = arr[i];
                int j;
                for (j = i; j >= gap && arr[j - gap] > tmp; j -= gap) {
                    arr[j] = arr[j - gap];
                }
                arr[j] = tmp;
            }
        }
    }


    /**
     * 5.归并排序: 拆分 合并
     * 时间复杂度: O(NlogN)
     * 空间复杂度: 对于数组来说, O(N)
     * 稳定性: 稳定排序
     *
     * @param arr
     * @param low
     * @param high 数组最后一个的下标
     */
    public static void mergeSort(int[] arr, int low, int high) {
        if (low < high) {
            // 1>拆分
            int mid = (low + high) / 2;
            // 递归解决左右两边子问题
            mergeSort(arr, low, mid);
            mergeSort(arr, mid + 1, high);
            // 2>左右归并
            Merge(arr, low, mid, high);
        }
    }

    /**
     * <2> 合并
     *
     * @param arr  数组
     * @param low  低下标
     * @param mid  中间位置数值下标
     * @param high 高下标
     */
    public static void Merge(int[] arr, int low, int mid, int high) {
        int[] pro = new int[high - low + 1]; // 一个辅助数组
        int i = low;
        int j = mid + 1;
        int index = 0;// 辅助数组索引
        // 1>两个数组从0开始比较,并将小的数放入辅助数组中
        while (i <= mid && j <= high) {
            if (arr[i] < arr[j])
                pro[index++] = arr[i++];
            else
                pro[index++] = arr[j++];
        }
        // 2>若;两个数组个数不同,比较完1>后,个数少的数组会有余留
        while (i <= mid)
            pro[index++] = arr[i++];
        while (j <= high)
            pro[index++] = arr[j++];
        // 3>将排序好的辅助数组中的值放入原数组
        for (int k = 0; k < index; k++)
            arr[k + low] = pro[k];
    }


    // 6. 堆排序:先建大堆,然后循环删除堆顶元素
    public static void heapSort(int[] arr, int size) {
        // 创建大堆
        createHeap(arr, size);

        // 循环删除堆顶
        for (int i = 0; i < size; i++) {
            heapPop(arr, size - i);
        }
    }

    // 堆删
    private static void heapPop(int[] arr, int size) {
        if (size <= 1)
            return;
        swap(arr, 0, size - 1);
        adjustDown(arr, size - 1, 0);
    }

    // 创建最大堆
    private static void createHeap(int[] arr, int size) {
        if (size <= 1) // 个数为1的话,直接返回
            return;
        int parent = (size - 1 - 1) / 2; // 从末尾起第一个非叶子结点
        for (int i = parent; i >= 0; i--) {
            adjustDown(arr, size, i);
        }
    }

    // 向下调整
    private static void adjustDown(int[] arr, int size, int i) {
        int parent = i;
        int child = 2 * parent + 1;
        while (child < size) {
            // 比较左右孩子结点大小
            if (child + 1 < size && arr[child] < arr[child + 1])
                child = child + 1;
            // 大孩子与父结点进行比较
            if (arr[parent] < arr[child])
                swap(arr, child, parent);
            // 继续向下调整
            parent = child; // child相当于一个标记,为与父结点进行交换的孩子的下标
            child = 2 * parent + 1;
        }
    }

    // 7. 快速排序

    /**
     * 时间复杂度: 最坏 O(N ^ 2)(如果数组是逆序的) 平均水平 O(NlogN)
     * 不稳定排序
     * @param arr
     * @param start
     * @param end
     */
    public static void quickSort(int[] arr, int start, int end) {
        int pivot = arr[start];
        int left = start;
        int right = end;

        while (left < right) {
            // 先从右边寻找比基准值小的数
            while (left < right && arr[right] > pivot)
                right--;
            // 左边开始寻找比基准值大的数
            while (left < right && arr[left] < pivot)
                left++;

            if (left < right)
                swap(arr, left, right);
        }
        // 此时left==right
        if (left - 1 > start) quickSort(arr, start, left - 1);
        if (right + 1 < end) quickSort(arr, right + 1, end);
    }

    public static void main(String[] args) {
        // int[] arr = {3, 1, 9, 7, 13, 0, 24, 67, 33};
        int arr[] = {6, 1, 2, 7, 4, 5, 10, 8};
        int len = arr.length;
        // insertSort(arr, len);
        // bubbleSort(arr, len);
        // mergeSort(arr, 0, len - 1);
        // shellSort(arr, len);
        // selectSort(arr, len);
        // heapSort(arr, len);
        quickSort(arr, 0, len - 1);
        for (int a : arr) {
            System.out.print(a + " ");
        }
    }
}

 

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