首页 Java java教程 快速掌握java排序算法-快速排序(图文)

快速掌握java排序算法-快速排序(图文)

Nov 29, 2019 pm 04:55 PM
快速排序 算法

快速掌握java排序算法-快速排序(图文)

概念

快速排序属于交换排序,主要步骤是使用基准元素进行比较,把小于基准元素的移动到一边,大于基准元素的移动到另一边。从而把数组分成两部分,然后再从这两部分中选取出基准元素,重复上面的步骤。过程如下:

(推荐视频:java视频教程)  

紫色:基准元素
绿色:大于基准元素
黄色:小于基准元素

file

这种思路叫做分治法。

基准元素

基准元素的选取可随机选取。下面使用中我会使用第一位的元素作为基准元素。

排序过程

排序拆分过程如下图:

紫色为基准元素,(每一轮都重新选取)
绿色为其他元素

第一轮
file

第二轮
file

第三轮
file

如上图所示:

若元素个数为n,因为排序过程中需要和全部元素都比较一遍,所以时间复杂度为O(n),
而平均情况下排序轮次需要logn轮,因此快速排序的平均时间复杂度为O(nlogn)。

排序的实现方法

实现方法有双边循环法和单边循环法

双边循环法

首选选取基准元素(pivot)4,并设置指针left和right,指向数组最左和最右两个元素,如下:
file

第一次循环,先从right指针指向的数据(rightData)开始和基准元素比较
若 rightData >= pivot,则right指针向左移动,若 rightData < pivot,则right指针不移动,切换到left指针
left指针指向数据(leftData)与基准元素比较,若 leftData < pivot,则left指针向右移动,若 leftData > pivot,交换left和right指向的元素。

第一轮指针移动完后,得到如下结构:

file

然后 left和right指向的元素进行交换:

file

第一轮循环结束,重新切换到right指针,重复上述步骤。

第二轮循环后,得:

file

第三轮循环后,得:

file

第四轮循环后,得:

file

判断到left和right指针指向同一个元素,指针停止移动,使pivot和指针元素进行交换,得:

file

宣告该轮循环结束,并根据Pivot元素切分为两部分,这两部分的数组再根据上述步骤进行操作。

实现代码

public class DoubleSort {
    public static void quickSort(int[] arr, int startIndex, int endIndex) {

        //递归结束条件
        if (startIndex >= endIndex) {
            return;
        }

        // 基准元素位置
        int pivotIndex = partition(arr, startIndex, endIndex);

        // 根据基准元素,分成两部分进行递归排序
        quickSort(arr, startIndex, pivotIndex - 1);
        quickSort(arr, pivotIndex + 1, endIndex);
    }

    public static int partition(int[] arr, int startIndex, int endIndex) {
        // 取第一个元素为基准元素,也可以随机抽取
        int pivot = arr[startIndex];
        int left = startIndex;
        int right = endIndex;

        while (left != right) {
            // 控制right指针比较并左移
            while (left < right && arr[right] >= pivot) {
                right--;
            }

            // 控制left指针比较并右移
            while (left < right && arr[left] <= pivot) {
                left++;
            }

            // 交换left和right指针所指向的元素
            if (left < right) {
                int temp = arr[right];
                arr[right] = arr[left];
                arr[left] = temp;
            }
        }

        arr[startIndex] = arr[left];
        arr[left] = pivot;
        return left;
    }

    public static void main(String[] args) {
        int[] arr = new int[]{4, 7, 6, 5, 3, 2, 8, 1};
        quickSort(arr, 0, arr.length - 1);
        System.out.println(Arrays.toString(arr));
    }
}
登录后复制

单边循环法

双边循环法从数组的两边比较并交换元素,而单边循环法则从数组的一边遍历,一直往后比较和交换,实现起来更加的简单。
过程如下:

首先也是选取基准元素pivot(可以随机选择)
设置一个mark指针指向数组的起始位置,代表小于基准元素的区域边界(不理解的就把它理解成是等会用来交换元素的就好了)

原始数组如下:

file

从基准元素下一位开始遍历数组
如果该元素大于基准元素,继续往下遍历
如果该元素小于基准元素,mark指针往右移,因为小于基准元素的区域边界增大了1(即小于基准元素的多了1位),所以mark就 +1,并且该元素和mark指向元素进行交换。

遍历到元素3时,因为3 < 4,所以mark右移

file

然后交换元素

file

然后就继续遍历,根据上面的步骤进行判断,后面的过程就不写了。

实现代码

public class SingleSort {
    public static void quickSort(int[] arr, int startIndex, int endIndex) {

        //递归结束条件
        if (startIndex >= endIndex) {
            return;
        }

        // 基准元素位置
        int pivotIndex = partition(arr, startIndex, endIndex);

        // 根据基准元素,分成两部分进行递归排序
        quickSort(arr, startIndex, pivotIndex - 1);
        quickSort(arr, pivotIndex + 1, endIndex);
    }

    /**
     * 分治(单边循环法)
     * @param arr
     * @param startIndex
     * @param endIndex
     * @return
     */
    public static int partition(int[] arr, int startIndex, int endIndex) {
        // 取第一个元素为基准元素,也可以随机抽取
        int pivot = arr[startIndex];
        int mark = startIndex;

        for(int i = startIndex + 1; i< arr.length; i++) {
            if (pivot < arr[i]) {
                continue;
            }

            mark ++;
            int temp = arr[mark];
            arr[mark] = arr[i];
            arr[i] = temp;
        }
        arr[startIndex] = arr[mark];
        arr[mark] = pivot;
        return mark;
    }

    public static void main(String[] args) {
        int[] arr = new int[]{4, 7, 6, 5, 3, 2, 8, 1};
        quickSort(arr, 0, arr.length - 1);
        System.out.println(Arrays.toString(arr));
    }
}
登录后复制

总结

本人也是初次接触算法,慢慢的去理解算法的思路和实现过程后,真是为自己以往写的算法感到羞愧。该文章也是为了加深自己对快排算法的印象,若文章有不足之处,恳请各位在下方留言补充。感谢各位的阅读。Thanks♪(・ω・)ノ。

参考资料:《小灰的算法之旅》 第四章。

本文来自php中文网,java教程栏目,欢迎学习!  

以上是快速掌握java排序算法-快速排序(图文)的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

CLIP-BEVFormer:显式监督BEVFormer结构,提升长尾检测性能 CLIP-BEVFormer:显式监督BEVFormer结构,提升长尾检测性能 Mar 26, 2024 pm 12:41 PM

写在前面&笔者的个人理解目前,在整个自动驾驶系统当中,感知模块扮演了其中至关重要的角色,行驶在道路上的自动驾驶车辆只有通过感知模块获得到准确的感知结果后,才能让自动驾驶系统中的下游规控模块做出及时、正确的判断和行为决策。目前,具备自动驾驶功能的汽车中通常会配备包括环视相机传感器、激光雷达传感器以及毫米波雷达传感器在内的多种数据信息传感器来收集不同模态的信息,用于实现准确的感知任务。基于纯视觉的BEV感知算法因其较低的硬件成本和易于部署的特点,以及其输出结果能便捷地应用于各种下游任务,因此受到工业

使用C++实现机器学习算法:常见挑战及解决方案 使用C++实现机器学习算法:常见挑战及解决方案 Jun 03, 2024 pm 01:25 PM

C++中机器学习算法面临的常见挑战包括内存管理、多线程、性能优化和可维护性。解决方案包括使用智能指针、现代线程库、SIMD指令和第三方库,并遵循代码风格指南和使用自动化工具。实践案例展示了如何利用Eigen库实现线性回归算法,有效地管理内存和使用高性能矩阵操作。

探究C++sort函数的底层原理与算法选择 探究C++sort函数的底层原理与算法选择 Apr 02, 2024 pm 05:36 PM

C++sort函数底层采用归并排序,其复杂度为O(nlogn),并提供不同的排序算法选择,包括快速排序、堆排序和稳定排序。

人工智能可以预测犯罪吗?探索CrimeGPT的能力 人工智能可以预测犯罪吗?探索CrimeGPT的能力 Mar 22, 2024 pm 10:10 PM

人工智能(AI)与执法领域的融合为犯罪预防和侦查开辟了新的可能性。人工智能的预测能力被广泛应用于CrimeGPT(犯罪预测技术)等系统,用于预测犯罪活动。本文探讨了人工智能在犯罪预测领域的潜力、目前的应用情况、所面临的挑战以及相关技术可能带来的道德影响。人工智能和犯罪预测:基础知识CrimeGPT利用机器学习算法来分析大量数据集,识别可以预测犯罪可能发生的地点和时间的模式。这些数据集包括历史犯罪统计数据、人口统计信息、经济指标、天气模式等。通过识别人类分析师可能忽视的趋势,人工智能可以为执法机构

改进的检测算法:用于高分辨率光学遥感图像目标检测 改进的检测算法:用于高分辨率光学遥感图像目标检测 Jun 06, 2024 pm 12:33 PM

01前景概要目前,难以在检测效率和检测结果之间取得适当的平衡。我们就研究出了一种用于高分辨率光学遥感图像中目标检测的增强YOLOv5算法,利用多层特征金字塔、多检测头策略和混合注意力模块来提高光学遥感图像的目标检测网络的效果。根据SIMD数据集,新算法的mAP比YOLOv5好2.2%,比YOLOX好8.48%,在检测结果和速度之间实现了更好的平衡。02背景&动机随着远感技术的快速发展,高分辨率光学远感图像已被用于描述地球表面的许多物体,包括飞机、汽车、建筑物等。目标检测在远感图像的解释中

算法在 58 画像平台建设中的应用 算法在 58 画像平台建设中的应用 May 09, 2024 am 09:01 AM

一、58画像平台建设背景首先和大家分享下58画像平台的建设背景。1.传统的画像平台传统的思路已经不够,建设用户画像平台依赖数据仓库建模能力,整合多业务线数据,构建准确的用户画像;还需要数据挖掘,理解用户行为、兴趣和需求,提供算法侧的能力;最后,还需要具备数据平台能力,高效存储、查询和共享用户画像数据,提供画像服务。业务自建画像平台和中台类型画像平台主要区别在于,业务自建画像平台服务单条业务线,按需定制;中台平台服务多条业务线,建模复杂,提供更为通用的能力。2.58中台画像建设的背景58的用户画像

实时加SOTA一飞冲天!FastOcc:推理更快、部署友好Occ算法来啦! 实时加SOTA一飞冲天!FastOcc:推理更快、部署友好Occ算法来啦! Mar 14, 2024 pm 11:50 PM

写在前面&笔者的个人理解在自动驾驶系统当中,感知任务是整个自驾系统中至关重要的组成部分。感知任务的主要目标是使自动驾驶车辆能够理解和感知周围的环境元素,如行驶在路上的车辆、路旁的行人、行驶过程中遇到的障碍物、路上的交通标志等,从而帮助下游模块做出正确合理的决策和行为。在一辆具备自动驾驶功能的车辆中,通常会配备不同类型的信息采集传感器,如环视相机传感器、激光雷达传感器以及毫米波雷达传感器等等,从而确保自动驾驶车辆能够准确感知和理解周围环境要素,使自动驾驶车辆在自主行驶的过程中能够做出正确的决断。目

Java快速排序技巧及注意事项 Java快速排序技巧及注意事项 Feb 25, 2024 pm 10:24 PM

掌握Java快速排序的关键技巧和注意事项快速排序(QuickSort)是一种常用的排序算法,其核心思想是通过选择一个基准元素,将待排序序列分割成独立的两部分,其中一部分的所有元素均小于基准元素,另一部分的所有元素均大于基准元素,然后对这两部分分别进行递归排序,最终得到有序序列。虽然快速排序在平均情况下的时间复杂度为O(nlogn),但在最坏情况下会退化为O

See all articles