0

0

Java中如何对数组进行快速排序

尼克

尼克

发布时间:2025-06-26 21:55:02

|

709人浏览过

|

来源于php中文网

原创

快速排序的核心是分而治之,通过选择基准值将数组分为两部分并递归排序。1. 选取基准值(如随机选择或三数取中法);2. 分区操作使小于基准值的元素在左、大于的在右;3. 递归对左右子数组排序。为优化性能,可对小数组切换插入排序。相比归并排序,快速排序原地排序且平均性能更优,但不稳定且最坏时间复杂度为o(n^2)。

Java中如何对数组进行快速排序

Java中快速排序数组的核心在于分而治之的思想。简单来说,就是选取一个基准值,将数组分成两部分,一部分小于基准值,一部分大于基准值,然后递归地对这两部分进行排序。

Java中如何对数组进行快速排序

解决方案

Java中如何对数组进行快速排序

快速排序是一种高效的排序算法,尤其适用于大型数据集。以下是在Java中实现快速排序的步骤和代码示例:

立即学习Java免费学习笔记(深入)”;

Java中如何对数组进行快速排序
  1. 选择基准值(Pivot): 从数组中选择一个元素作为基准值。选择方式会影响性能,常见的有选择第一个元素、最后一个元素、中间元素或随机元素。

  2. 分区(Partitioning): 重新排列数组,所有小于基准值的元素都放在基准值之前,所有大于基准值的元素都放在基准值之后。基准值位于它最终排序后的位置。

  3. 递归排序: 递归地对基准值之前的子数组和基准值之后的子数组进行快速排序。

public class QuickSort {

    public static void quickSort(int[] arr, int low, int high) {
        if (low < high) {
            int partitionIndex = partition(arr, low, high);

            quickSort(arr, low, partitionIndex - 1);
            quickSort(arr, partitionIndex + 1, high);
        }
    }

    private static int partition(int[] arr, int low, int high) {
        int pivot = arr[high];
        int i = (low - 1); // Index of smaller element
        for (int j = low; j < high; j++) {
            // If current element is smaller than or equal to pivot
            if (arr[j] <= pivot) {
                i++;

                // swap arr[i] and arr[j]
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }

        // swap arr[i+1] and arr[high] (or pivot)
        int temp = arr[i + 1];
        arr[i + 1] = arr[high];
        arr[high] = temp;

        return i + 1;
    }

    public static void main(String[] args) {
        int[] arr = {10, 7, 8, 9, 1, 5};
        int n = arr.length;
        quickSort(arr, 0, n - 1);

        System.out.println("Sorted array:");
        for (int i = 0; i < n; ++i)
            System.out.print(arr[i] + " ");
        System.out.println();
    }
}

这段代码首先定义了一个 quickSort 方法,它接受数组、低索引和高索引作为参数。partition 方法负责将数组分成两部分,并返回基准值的索引。main 方法用于测试快速排序算法。

快速排序的关键在于 partition 函数,它通过遍历数组,将小于等于基准值的元素放到基准值的左边,大于基准值的元素放到右边。

快速排序的平均时间复杂度是 O(n log n),但在最坏情况下(例如,数组已经排序),时间复杂度会退化到 O(n^2)。为了避免最坏情况,可以采用随机选择基准值的方法。

快速排序是不稳定的排序算法,即相等元素的相对位置在排序后可能会发生改变。

快速排序通常比其他 O(n log n) 排序算法(如归并排序)更快,因为它具有较小的常数因子。

如何选择合适的基准值以优化快速排序的性能?

选择基准值是快速排序性能的关键。理想情况下,基准值应该尽可能地将数组分成大小相等的两部分。以下是一些常见的基准值选择策略:

  • 选择第一个元素或最后一个元素: 这是最简单的策略,但如果数组已经排序或接近排序,会导致最坏情况 O(n^2) 的时间复杂度。

    j2me3D游戏开发简单教程 中文WORD版
    j2me3D游戏开发简单教程 中文WORD版

    本文档主要讲述的是j2me3D游戏开发简单教程; 如今,3D图形几乎是任何一部游戏的关键部分,甚至一些应用程序也通过用3D形式来描述信息而获得了成功。如前文中所述,以立即模式和手工编码建立所有的3D对象的方式进行开发速度很慢且很复杂。应用程序中多边形的所有角点必须在数组中独立编码。在JSR 184中,这称为立即模式。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看

    下载
  • 选择中间元素: 可以稍微改善性能,但仍然可能在某些情况下导致较差的性能。

  • 随机选择: 从数组中随机选择一个元素作为基准值。这种方法可以有效地避免最坏情况,因为无论输入数组的初始状态如何,选择到坏基准值的概率都很低。

  • 三数取中(Median-of-Three): 选择数组的第一个元素、中间元素和最后一个元素,然后取这三个元素的中位数作为基准值。这种方法在实践中表现良好,因为它通常可以选到一个接近中间值的基准值。

private static int partition(int[] arr, int low, int high) {
    // 三数取中
    int mid = low + (high - low) / 2;
    int pivot = medianOfThree(arr, low, mid, high);

    // 将基准值放到high位置
    swap(arr, pivot, high);

    pivot = arr[high];
    int i = (low - 1); // Index of smaller element
    for (int j = low; j < high; j++) {
        // If current element is smaller than or equal to pivot
        if (arr[j] <= pivot) {
            i++;

            // swap arr[i] and arr[j]
            swap(arr, i, j);
        }
    }

    // swap arr[i+1] and arr[high] (or pivot)
    swap(arr, i + 1, high);

    return i + 1;
}

private static int medianOfThree(int[] arr, int a, int b, int c) {
    if ((arr[a] - arr[b]) * (arr[c] - arr[a]) >= 0) {
        return a;
    } else if ((arr[b] - arr[a]) * (arr[c] - arr[b]) >= 0) {
        return b;
    } else {
        return c;
    }
}

private static void swap(int[] arr, int i, int j) {
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

使用三数取中法,可以有效地减少最坏情况发生的概率,提高快速排序的整体性能。

如何处理快速排序中的小数组以提高效率?

当快速排序递归到足够小的子数组时,快速排序的优势会减弱。这是因为快速排序的递归调用和分区操作有一定的开销。对于小数组,插入排序等简单排序算法可能更有效。

一种常见的优化方法是,当子数组的大小小于某个阈值时,切换到插入排序。这个阈值通常在 5 到 20 之间,具体值取决于硬件和数据特性。

private static void quickSort(int[] arr, int low, int high) {
    int INSERTION_SORT_THRESHOLD = 10; // 阈值

    if (high - low + 1 < INSERTION_SORT_THRESHOLD) {
        insertionSort(arr, low, high);
    } else if (low < high) {
        int partitionIndex = partition(arr, low, high);

        quickSort(arr, low, partitionIndex - 1);
        quickSort(arr, partitionIndex + 1, high);
    }
}

private static void insertionSort(int[] arr, int low, int high) {
    for (int i = low + 1; i <= high; i++) {
        int key = arr[i];
        int j = i - 1;

        /* Move elements of arr[0..i-1], that are
           greater than key, to one position ahead
           of their current position */
        while (j >= low && arr[j] > key) {
            arr[j] = arr[j + 1];
            j = j - 1;
        }
        arr[j + 1] = key;
    }
}

这段代码在 quickSort 方法中添加了一个判断,如果子数组的大小小于 INSERTION_SORT_THRESHOLD,就调用 insertionSort 方法进行排序。

通过这种方式,可以避免快速排序在小数组上的低效操作,从而提高整体排序效率。

快速排序与归并排序相比,有什么优缺点?

快速排序和归并排序都是常用的 O(n log n) 排序算法,但它们在实现方式和性能特点上有所不同。

快速排序的优点:

  • 原地排序: 快速排序是一种原地排序算法,只需要很小的额外空间(通常是 O(log n) 的栈空间用于递归)。
  • 平均性能好: 在平均情况下,快速排序比归并排序更快,因为它具有较小的常数因子。
  • 缓存友好: 快速排序在内存中是连续访问数据的,因此缓存命中率较高。

快速排序的缺点:

  • 最坏情况性能差: 在最坏情况下(例如,数组已经排序),快速排序的时间复杂度会退化到 O(n^2)。
  • 不稳定: 快速排序是一种不稳定的排序算法,相等元素的相对位置在排序后可能会发生改变。

归并排序的优点:

  • 稳定: 归并排序是一种稳定的排序算法,相等元素的相对位置在排序后不会发生改变。
  • 最坏情况性能好: 归并排序的时间复杂度始终是 O(n log n),不会出现最坏情况。
  • 易于并行化: 归并排序可以很容易地并行化,从而提高排序速度。

归并排序的缺点:

  • 需要额外空间: 归并排序需要 O(n) 的额外空间用于合并操作。
  • 常数因子较大: 归并排序的常数因子比快速排序大,因此在平均情况下速度较慢。
  • 缓存不友好: 归并排序在合并过程中需要频繁地在内存中跳跃访问数据,因此缓存命中率较低。

总的来说,如果对排序的稳定性有要求,或者需要保证最坏情况下的性能,那么归并排序是一个更好的选择。如果对空间复杂度有要求,并且可以接受不稳定的排序结果,那么快速排序通常是更快的选择。

在实际应用中,可以根据具体的需求和数据特点选择合适的排序算法。有时候,也可以将快速排序和归并排序结合起来使用,例如,先使用快速排序将数组分成多个小块,然后使用归并排序将这些小块合并起来。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

442

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

605

2023.08.10

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

494

2023.08.14

Kotlin Android模块化架构与组件化开发实践
Kotlin Android模块化架构与组件化开发实践

本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

24

2026.03.09

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

80

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

187

2026.03.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

339

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

116

2026.03.04

Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

180

2026.03.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4.3万人学习

C# 教程
C# 教程

共94课时 | 11.1万人学习

Java 教程
Java 教程

共578课时 | 80.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号