图解快速排序

什么是快速排序?

快速排序(Quicksort)是对冒泡排序的一种改进

快速排序由C. A. R. Hoare在1960年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列

思路

假设我们现在对 (6 1 2 7 9 3 4 5 10 8 )这 10 个数字进行排序。首先在这个序列中随便找一个数最为 轴心点。为了方便,就让第一个数 6 作为基准数吧。接下来,需要将这个序列中所有比基准数大的数放在 6 的右边,比基准数小的数放在 6 的左边,类似下面这种排序
在这里插入图片描述
在初始状态下,数字 6 在序列的第一位。我们的目标是将6 挪到序列中间的某个位置,假设这个位置是 k,现在就需要寻找这个 k,并且以第 k 位为分界点,左边的是都小于等于 6,右边的书都大于等于 6

方法其实很简单:分别从初始序列 (6 1 2 7 9 3 4 5 10 8 )两端开始探测。先从 找一个小于 6 的数,再从 找一个大于 6 的数,然后交换它们。

完整的动画演示

相信聪明的你们看了这动画之后都已经会了
在这里插入图片描述
快速排序之所以比较快,是因为相比冒泡排序,每次交换是跳跃式的。每次排序的时候
设置一个基准点,将小于等于基准点的数全部放到基准点的左边,将大于等于基准点的数全
部放到基准点的右边。这样在每次交换的时候就不会像冒泡排序一样只能在相邻的数之间进
行交换,交换的距离就大得多了。因此总的比较和交换次数就少了,速度自然就提高了。当
然在最坏的情况下,仍可能是相邻的两个数进行了交换。因此快速排序的最差时间复杂度和
冒泡排序是一样的,都是 O(N 2 ),它的平均时间复杂度为 O (NlogN)。其实快速排序是基于一
种叫做“二分”的思想

代码实现

package com.java.springtest.sort;

/**
 * @author Woo_home
 * @create by 2020/2/8
 */
public class Demo {

    public static int[] sort(int[] num,int left,int right) {
        if (left > right) {
            return null;
        }
        int temp = num[left];
        int i = left;
        int j = right;
        while (i < j) {
            while (num[j] >= temp && i < j) {
                j--;
            }
            while (num[i] <= temp && i < j){
                i++;
            }
            if (i < j) {
                int t = num[i];
                num[i] = num[j];
                num[j] = t;
            }
        }
        num[left] = num[i];
        num[i] = temp;

        sort(num,left,i-1);
        sort(num,i+1,right);
        return num;
    }

    public static void main(String[] args) {
        int[] num = {6,1,2,7,9,3,4,5,10,8};
        int[] sort = sort(num, 0, num.length-1);
        for (int i : sort) {
            System.out.print(i + " ");
        }
    }
}

输出:
在这里插入图片描述

### 快速排序算法图解 快速排序是一种基于分治策略的高效排序方法[^2]。该算法通过递归方式将数组划分为较小子数组,分别对这些子数组进行排序,最终得到有序序列。 #### 基本流程描述 1. **选取基准值**:从待排序列中挑选一个元素作为基准(pivot)。通常可以选择第一个元素、最后一个元素或者中间位置的元素。 2. **分区操作**:重新排列列表中的其他元素,使得所有小于基准值的元素位于其左边,大于等于基准值的元素位于右边;此时基准处于已排好序的位置上。 3. **递归处理**:对于划分后的两个部分重复上述过程直到不能再分割为止。 4. **合并结果**:由于每次都是原地修改数组,则无需额外空间来存储临时数据结构,在完成最后一次迭代后即获得完整的升序/降序排列。 #### 图形化展示 假设有一个无序整型数组 `[9, 7, 5, 11, 12, 2, 14, 3, 10, 6]` 需要按照从小到大顺序排列: - 初始状态: |索引| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |--|--|--|--|----|----|--|-----|--|-----|--| |数值| 9 | 7 | 5 | 11 | 12 | 2 | 14 | 3 | 10 | 6 | - 设定 `low=0`, `high=length-1`; 选定最右侧元素 (`arr[high]=6`) 为本次循环的基准值; - 开始遍历比较并交换满足条件的数据项直至指针交错相遇停止,形成如下所示的新布局: |索引| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |--|--|--|--|----|----|--|-----|--|-----|--| |数值| 5 | 7 | 3 | 2 | 12 | 9 | 14 | 6 | 10 | 11 | - 继续针对左右两侧未排序区间执行相同逻辑... ```python def quicksort(arr): if len(arr) <= 1: return arr else: pivot = arr[-1] less_than_pivot = [x for x in arr[:-1] if x < pivot] greater_or_equal_to_pivot = [x for x in arr[:-1] if x >= pivot] return quicksort(less_than_pivot) + [pivot] + quicksort(greater_or_equal_to_pivot) unsorted_list = [9, 7, 5, 11, 12, 2, 14, 3, 10, 6] print(quicksort(unsorted_list)) ``` 在最优情况下,时间复杂度可以达到 \(O(n \log n)\),这是因为树的高度大约为 \(\log_2n\) 层,并且每一层都要访问几乎所有的节点一次[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值