数据结构与算法读书笔记-11 排序算法2

2种时间复杂度为O(nlogn)的排序算法

原地排序算法:特指空间复杂度是 O(1) 的排序算法

稳定性:如果待排序的序列中存在值相等的元素,过排序之后,相等元素之间原有的先后顺序不变。

 

归并排序 - 非原地排序&&稳定

private static void recursiveDivide(int[] origin, int start, int end) {
        // 确认停止条件
        if (start >= end) {
            return;
        }
        int mid = (start + end) / 2;
        // 拆分也可以不用递归
        recursiveDivide(origin, start, mid);
        recursiveDivide(origin, mid + 1, end);
        merge(origin, start, mid, end);
    }

    private static void merge(int[] origin, int start, int mid, int end) {      // 要理解两个有序数组 比较过程
        int[] temp = new int[end - start + 1];
        int l = start, r = mid + 1;
        // 装满temp
        for (int k = 0; k < temp.length; k++) {
            // 左边元素遍历完
            if (l > mid) {
                temp[k] = origin[r];
                continue;
            }
            // 右边元素遍历完
            if (r > end) {
                temp[k] = origin[l++];
                continue;
            }
            // 装元素
            if (origin[l] < origin[r]) {
                // 指针移动
                temp[k] = origin[l++];
            } else {
                temp[k] = origin[r++];
            }
        }
        // 复制数组
        if (end - start + 1 >= 0) {
            System.arraycopy(temp, 0, origin, start, end - start + 1);
        }
    }

    private static void sort(int[] origin) {
        int length = origin.length;
        if (length <= 1) {
            return;
        }
        recursiveDivide(origin, 0, length - 1);
        System.out.println(Arrays.toString(origin));
    }

    public static void main(String[] args) {
        int[] arrays = {7, 4, 2,2};
        sort(arrays);
    }

 

快速排序 - 原地排序&&不稳定

private static void recursive(int[] origin, int start, int end) {
        if (start >= end) {
            return;
        }
        int p = sort(origin, start, end);
        // 分区点已经比较过,不继续参与分区,否则遇到相同元素会死循环
        recursive(origin, start, p - 1);
        recursive(origin, p + 1, end);
    }

    /**
     * int i 记录小半区
     *
     * @param origin origin
     * @param start  start
     * @param end    end
     * @return 分割点
     */
    private static int sort(int[] origin, int start, int end) {
        // int i 记录
        int i = start;
        for (int j = i; j < end; j++) {
            if (origin[j] < origin[end]) {
                swap(origin, j, i);
                i++;
            }
        }
        // 确保总有一个元素在已处理区域
        swap(origin, end, i);
        return i;
    }

    private static void swap(int[] array, int from, int to) {
        int temp = array[from];
        array[from] = array[to];
        array[to] = temp;
    }

    public static void main(String[] args) {
        int[] a = new int[]{3, 4, 7, 3};
        recursive(a, 0, a.length - 1);
        System.out.println(Arrays.toString(a));
    }

 

posted @ 2019-10-30 22:24  渠成  阅读(76)  评论(0)    收藏  举报