算法复习之 快速排序(不使用交换的快速排序)

快速排序的思想很简单,就是每次确定一个mid位置,让该位置的数在整个数组中保持有序之后,再对其两边的子数组分别进行快速排序。
因此如何将一个选定的数变为全局有序变成了快速排序的关键问题。
提供一种思路:这种思路采用的是覆盖替换的方式,具体的,我们把pivot位置的元素存起来,准备放到一个位置。我们使指针 l 指向数组头,r指向数组尾,然后通过一定的策略缩小这个区间,最后就会得到一个位置用来存放pivot。pivot一定会放到l和r之间或之上,由于要避免交换而且要将比pivot大的都放到pivot右边,比pivot小的放到他左边,第一轮,我们选取一个元素放到初始pivot的位置(这样可以避免交换),也就是选一个元素放到l的位置,那肯定要选取一个比pivot小的元素放到 l ,我们通过向前移动r来寻找这个数,找到之后可以确保r右边的数都比pivot大(或等)。接着,我们要选取一个元素放到位置r,那肯定是选取一个比pivot大的元素。我们可以通过向后移动 l 来寻找第一个比pivot大的数,这样可以确保l之前的数字一定比pivot小(或等)。找到之后,l位置又需要被l和r之间比pivot小的元素替换。依次执行上述步骤,当l == r时,说明此时l的位置就是pivot该在的位置,此时pivot左边的元素都比他小,pivot右边的元素都比他大(或等)。

public static int find(int[] arr, int l, int r) {
        int pivot = arr[l];
        while(l < r) {
            while(l < r && arr[r] >= pivot) r --;
            arr[l] = arr[r];
            while(l < r && arr[l] <= pivot) l ++;
            arr[r] = arr[l];
        }
        arr[l] = pivot;
        return l;
    }

    public static void quickSort(int[] arr, int l, int r) {
        if (l < r) {
            int mid = find(arr, l, r);
            quickSort(arr, l, mid - 1);
            quickSort(arr, mid + 1, r);
        }
    }
posted @ 2021-04-28 23:33  Cruel_King  阅读(274)  评论(0编辑  收藏  举报