【数据结构排序算法篇】----快速排序【实战演练】

在这里插入图片描述

作为一名对技术充满热情的学习者,我一直以来都深刻地体会到知识的广度和深度。在这个不断演变的数字时代,我远非专家,而是一位不断追求进步的旅行者。通过这篇博客,我想分享我在某个领域的学习经验,与大家共同探讨、共同成长。请大家以开放的心态阅读,相信你们也会在这段知识之旅中找到启示。


前言

学习快速排序,最重要的就是学会分治思想,对于pivot的选择有很多种,这让我们产生了如何使用更加合适的pivot时代码变得更加高效,下面我们就开始谈谈快速排序。


一、什么是快速排序

快速排序是一个高效的排序算法,由C.A.R. Hoare在1960年提出。因其平均时间复杂度为O(n log n)而被广泛使用,并且还具有原地排序(不需要额外大量的内存空间)的优点。这种算法的基本思想是分治策略,通过一个称为"pivot"(中枢或枢轴)的元素来将原数组分割成两个子数组。

快速排序的基本步骤包括:

  1. 选择pivot(枢轴元素)
    从数组中选择一个元素作为pivot。选择方法有多种,例如选择第一个元素、最后一个元素、中间的元素,或者随机选择一个元素。选择不同的pivot可能会影响算法的性能。

  2. 分区操作
    重新排列数组,使得所有比pivot小的元素都排在pivot的前面,而所有比pivot大的元素都排在后面。这一步结束后,pivot就位于其最终排序后的位置。

  3. 递归排序子数组
    递归地在pivot左侧和右侧的子数组上重复前面的步骤,直到子数组的大小缩减到1或0,此时算法结束。

在最坏的情况下,例如当输入数组已经是排序状态或逆排序状态时,每次分区只缩减一个元素,这使得快速排序的时间复杂度退化为O(n^2)。然而,通过随机选择pivot,可以降低这种最坏情况发生的概率,使得快速排序在平均情况下展现出良好性能。

快速排序通常被认为在实际应用中比其他O(n log n)排序算法,如归并排序或堆排序,更快。因为其内部循环(inner
loop)可以有效地在多种现代架构上实现。尽管如此,在选择快速排序的实现时,还应考虑数据的特点以及实际性能表现。

二、三数取中

这里的数组是 {8, 3, 1, 7, 0, 10, 2},我们将使用“三数取中”方法来选择pivot,这在实践中是一个比较好的折衷方法。

在“三数取中”方法中,我们将比较数组的第一个元素、中间元素和最后一个元素,然后选择这三个数的中位数作为pivot。在我们的示例数组中,这将是 8(第一个元素),7(中间元素),和 2(最后一个元素),所以pivot将是 7

以下是Java代码演示了如何对这个数组执行快速排序:

public class QuickSortExample {
   
    public static void quickSort(int[] arr, int low, int high) {
   
        if (low < high) {
   
            // 找到pivot所在位置
            int pivotIndex = partition(arr, low, high);

            // 对pivot左边的数组递归排序
            quickSort(arr, low, pivotIndex - 1);

            // 对pivot右边的数组递归排序
            quickSort(arr, pivotIndex + 1, high);
        }
    }

    private static int partition(int[] arr, int low, int high) {
   
        // “三数取中”作为pivot
        int pivot = medianOfThree(arr, low, high);
        
        // 将pivot移到数组末尾
        swap(arr, high, medianOfThreeIndex(arr, low, high));

        int border = low - 1; // 边界
        for (int i = low; i < high; i++) {
   
            // 所有小于pivot的元素移到左边
            if (arr[i] 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值