问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

快速排序算法详解:从基本思想到代码实现

创作时间:
作者:
@小白创作中心

快速排序算法详解:从基本思想到代码实现

引用
CSDN
1.
https://blog.csdn.net/qq_39181839/article/details/109478094

快速排序是一种非常高效的排序算法,采用分治策略来把一个序列分为较小和较大的两个子序列,然后递归地排序两个子序列。本文将通过图文结合的方式,详细解释快速排序的原理和实现过程。

基本思想

快速排序的核心思想是选择一个基准元素(base),通过一趟排序将待排序的数据分割成两部分,其中一部分的所有数据都比另一部分的所有数据小,然后再对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

图文详解

以数组 [3,4,6,1,2,4,7] 为例,选择第一个元素 3 作为基准元素(base)。定义两个指针(小熊 l 和小熊 r),分别从两端开始扫描。从右向左找比 base 小的数,替换 l 所在位置的元素;再从左往右找比 base 大的数,替换 r 所在位置的元素。重复此过程直至两个指针重合,此时 base 替换此元素,第一轮结束。再递归排序 base 左右两部分的元素。

初始状态

让小熊 l 指向序列的最左边,指向数字 3。让小熊 r 指向序列的最右边,指向数字 7。

第一轮扫描

小熊 r 向左移动,直到找到比 base(3)小的数(2),替换此时小熊 l 所在位置的元素。

替换后的序列为 [2,4,6,1,2,4,7]。

小熊 l 向右移动,直到找到比 base 大的数(4),替换此时小熊 r 所在位置的元素。

替换后的序列为 [2,1,6,1,4,4,7],小熊 r 再次向左移动。

小熊 l 向右移动,直到找到比 base 大的数(6),替换此时小熊 r 所在位置的元素。

此时小熊 l 和小熊 r 指向同一元素。

base(3)替换此元素。

第一轮扫描完成,序列为 [2,1,3,6,4,4,7]。此时 base 左边的元素都比它小,右边的元素都比它大,再对这两部分进行上述操作。

代码实现

以下是两种不同风格的快速排序代码实现:

实现一

public static void quickSort(int nums[], int start, int end) {
    // 数组有多个元素进行排序
    if (start < end) {
        int base = nums[start]; // 以要进行排序数组第0个元素为base
        int left = start; // 左指针
        int right = end; // 右指针
        while (left < right) {
            // 从右向左找,比base大,right--
            while (left < right && nums[right] >= base) {
                right--;
            }
            // 比base小,替换left所在位置的数字
            nums[left] = nums[right];
            // 从左向右找,比base小,left++
            while (left < right && nums[left] <= base) {
                left++;
            }
            // 比base大,替换right所在位置的数字
            nums[right] = nums[left];
        }
        nums[left] = base; // 此时left=right,用base替换这个位置的数字
        // 排列比base小的数字的数组
        quickSort(nums, start, left - 1);
        // 排列比base大的数字的数组
        quickSort(nums, left + 1, end);
    }
}

实现二

public void quickSort(int[] arr, int left, int right) {
    if (left < right) {
        int pos = partition(arr, left, right);
        quickSort(arr, left, pos - 1);
        quickSort(arr, pos + 1, right);
    }
}

public int partition(int[] arr, int left, int right) {
    int base = arr[left];
    while (left < right) {
        while (left < right && arr[right] >= base) {
            right--;
        }
        arr[left] = arr[right];
        while (left < right && arr[left] <= base) {
            left++;
        }
        arr[right] = arr[left];
    }
    arr[left] = base;
    return left;
}

采用分治的思想,先找到每次分割的点 pos,再排序。通过递归的方式,不断将数组分为更小的部分,直到每个部分都排序完成。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号