Java快速排序的实现详细代码及通俗解释

 更新时间:2025年02月19日 09:22:54   作者:卖房卖车只为一心敲Java  
这篇文章主要介绍了Java快速排序实现的相关资料,快速排序是一种高效的排序算法,通过选择一个基准值将数组分成两部分,左边的元素比基准值小,右边的元素比基准值大,然后递归地对这两部分进行排序,需要的朋友可以参考下

快速排序的基本概念:

快速排序的核心就是选择一个基准值,然后将数组分成两部分:

  • 左边:比基准值小的元素。
  • 右边:比基准值大的元素。 然后递归地对左右两部分继续进行这个过程,直到每部分都排好序。

来,我们用现实生活中的例子来理解!

假设你在整理一堆数字卡片📇,你想把这些卡片按从小到大的顺序排列。快速排序就像是你站在桌子旁边,对这些卡片进行一次大分拣📦,然后不断地把小卡片和大卡片分成左右两边,直到它们都排好位置。

举个具体的例子:

你有这样一堆数字:
[8, 3, 5, 1, 9, 6]

第一步:选一个基准值(pivot)

我们从中间选一个数字作为基准值,比如选择 6 作为基准。

第二步:分拣

  • 比6小的数字放到左边,即:[3, 5, 1]
  • 比6大的数字放到右边,即:[8, 9]
  • 基准值6就放在中间。

现在我们有了这样的分拣结果: 左边:[3, 5, 1]中间:6右边:[8, 9]

第三步:递归处理左边和右边

  • 对左边的数组 [3, 5, 1] 再次进行快速排序

    • 选择基准值:3
    • 左边:[1] (比3小)
    • 右边:[5] (比3大)

    现在左边排好了:[1, 3, 5]

  • 右边的数组 [8, 9]

    • 这个部分已经排好了,因为8比9小。

第四步:组合结果

现在我们把所有部分组合起来:

  • 左边:[1, 3, 5]
  • 基准值:6
  • 右边:[8, 9]

最终得到的排序结果就是:
[1, 3, 5, 6, 8, 9]

简单总结快速排序的步骤:

  • 选择基准值:选一个数字作为基准值,通常选择数组中的某个元素。
  • 分拣:把比基准值小的放左边,比基准值大的放右边。
  • 递归:对左边和右边的部分继续进行相同的操作。
  • 组合结果:最终把排好序的部分拼在一起。

用生活中的例子来理解:

Imagine 你要整理一个大抽屉里的袜子🧦。你先挑出一只作为“基准袜”,比如中等长度的,然后开始整理:

  • 比基准袜短的放一边(左边)。
  • 比基准袜长的放另一边(右边)。

接着你再分别整理两边的袜子,按照同样的方式继续分拣,直到所有的袜子都按长短排好顺序!

快速排序的优势

快速排序的效率很高,因为它每次都将问题规模减半。通过把问题分解成小问题,它能快速解决排序问题。平均时间复杂度是 O(n log n),在大多数情况下比冒泡排序(时间复杂度 O(n²))要快得多。

快速排序的完整Java代码:

public class QuickSortExample {

    // 快速排序的主方法,传入数组、最小索引和最大索引
    public static void quickSort(int[] arr, int low, int high) {
        // 如果低索引小于高索引,说明数组还没排序完
        if (low < high) {
            // 找到基准元素的位置,并把数组分成两部分
            int pivotIndex = partition(arr, low, high);
            
            // 递归地对基准左边部分进行快速排序
            quickSort(arr, low, pivotIndex - 1);
            // 递归地对基准右边部分进行快速排序
            quickSort(arr, pivotIndex + 1, high);
        }
    }

    // 分区方法:选择一个基准值,把小于基准的元素放在左边,大于基准的放在右边
    private static int partition(int[] arr, int low, int high) {
        // 选择最右边的元素作为基准
        int pivot = arr[high];
        
        // i是用来追踪小于基准值的元素的位置
        int i = low - 1; 

        // 遍历数组,找到所有小于基准值的元素
        for (int j = low; j < high; j++) {
            // 如果当前元素小于或等于基准值
            if (arr[j] <= pivot) {
                i++; // 增加i,准备交换小元素的位置
                
                // 交换arr[i]和arr[j],把小元素放到前面
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }

        // 最后,把基准值放到正确的位置(中间)
        int temp = arr[i + 1];
        arr[i + 1] = arr[high];
        arr[high] = temp;

        // 返回基准值的正确位置
        return i + 1;
    }

    // 测试快速排序方法的主函数
    public static void main(String[] args) {
        // 定义一个需要排序的数组
        int[] arr = {8, 3, 5, 1, 9, 6};

        // 打印排序前的数组
        System.out.println("排序前的数组:");
        printArray(arr);

        // 调用快速排序方法,排序整个数组
        quickSort(arr, 0, arr.length - 1);

        // 打印排序后的数组
        System.out.println("排序后的数组:");
        printArray(arr);
    }

    // 辅助方法:打印数组中的所有元素
    private static void printArray(int[] arr) {
        for (int num : arr) {
            System.out.print(num + " ");
        }
        System.out.println();
    }
}

代码详解:

  • quickSort 方法:这是快速排序的主方法。它接收一个数组、最小索引(low)和最大索引(high)。如果当前子数组的大小大于1(low < high),它会找到基准值的正确位置,然后递归地排序左右两部分。
  • partition 方法:这个方法的作用是将数组分成两部分
    • 左边是比基准值小或相等的元素。
    • 右边是比基准值大的元素。
      它返回的是基准值最终所在的位置,这样我们知道从哪里把数组一分为二。
  • printArray 方法:这个方法是一个辅助方法,用来打印数组内容,方便我们查看排序前后的效果。

解释这个例子的通俗版本:

  • 选基准值
    比如我们从数组 [8, 3, 5, 1, 9, 6] 中选了 6 作为基准值。这个基准值就像是一条“分界线”,我们要把小于 6 的元素放到左边,把大于 6 的元素放到右边。
  • 分左右
    遍历数组,依次将小于 6 的元素放在数组的前面,大于 6 的元素放到数组的后面。比如 35, 和 1 会被移到前面,89 会放到后面,6 作为基准值就在中间。
  • 递归处理
    然后我们对左边部分 [3, 5, 1] 和右边部分 [8, 9] 继续做相同的分拣,直到每个部分都只有一个元素为止。
  • 排序完成
    最后,所有的元素就按照从小到大的顺序排好了,结果是 [1, 3, 5, 6, 8, 9]

排序前的数组:
8 3 5 1 9 6 
排序后的数组:
1 3 5 6 8 9 

小结:

  • 快速排序通过挑选一个基准值,然后将数组分为两部分:左边比基准小,右边比基准大。
  • 然后对左右两部分继续递归进行快速排序,直到数组排序完毕。
  • 整个过程其实就是不停地“分拣”元素,类似于你把大小不同的物品进行快速分拣,最后得到排序结果。

总结 

到此这篇关于Java快速排序实现的文章就介绍到这了,更多相关Java快速排序实现内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • maven项目切换JDK踩坑指南分享

    maven项目切换JDK踩坑指南分享

    文章介绍了如何在Windows系统中配置多版本JDK环境,并解决环境变量配置失效的问题,同时,还提供了在IntelliJ IDEA中配置不同项目JDK版本的方法
    2024-11-11
  • 使用maven创建web项目的方法步骤(图文)

    使用maven创建web项目的方法步骤(图文)

    本篇文章主要介绍了使用maven创建web项目的方法步骤,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01
  • java实现的日期时间转换工具类完整示例

    java实现的日期时间转换工具类完整示例

    这篇文章主要介绍了java实现的日期时间转换工具类,结合完整实例形式分析了java针对日期时间常见的转换、计算、格式化等相关操作与封装技巧,需要的朋友可以参考下
    2019-10-10
  • java接口性能从20s优化到500ms示例详解

    java接口性能从20s优化到500ms示例详解

    这篇文章主要为大家介绍了java接口性能从20s优化到500ms的操作技巧示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • SpringBoot实现上传文件到AWS S3的代码

    SpringBoot实现上传文件到AWS S3的代码

    这篇文章主要介绍了SpringBoot实现上传文件到AWS S3的代码,帮助大家更好的理解和使用springboot框架,感兴趣的朋友可以了解下
    2020-10-10
  • java结束进程的实例代码

    java结束进程的实例代码

    java结束程序进程的方法很简单,只要一句代码就行,大家参考使用吧
    2013-12-12
  • java组件smartupload实现上传文件功能

    java组件smartupload实现上传文件功能

    这篇文章主要为大家详细介绍了java组件smartupload实现上传文件功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10
  • springboot项目中controller层与前端的参数传递方式

    springboot项目中controller层与前端的参数传递方式

    这篇文章主要介绍了springboot项目中controller层与前端的参数传递方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • StringBuilder为什么线程不安全深入讲解

    StringBuilder为什么线程不安全深入讲解

    这篇文章主要给大家介绍了关于StringBuilder为什么线程不安全的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用StringBuilder线程具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-08-08
  • Java下载https文件并上传阿里云oss服务器

    Java下载https文件并上传阿里云oss服务器

    这篇文章主要介绍了Java下载https文件并上传到阿里云oss服务器,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01

最新评论