Java实现十大经典排序算法之快速排序

0 算法简介

快速排序是一种高效率排序算法,它是对冒泡排序的一种改进,它也是一种不稳定排序算法快速排序的核心是比较、交换和递归。 在待排序数组中指定一个基准元素pivot(一般选取数组首元素),使得数组排序之后基准元素左边的所有元素均小于它,右边的元素均大于它,重复以上过程递归地对左右子集合进行排序。

平均时间复杂度 :O(nlogn) ,最坏时间复杂度为O(n2)

1 算法步骤

  • 定义一个基准位pivot(可选定数组的第一个值),比如以左边的低位为基准位:arraylow,比基准位的值大的放在右边,基准位值小的放在左边(根据具体的排序需求来)

  • 定义两个指针作为哨兵,分别为left和right且left < right,当left > right时退出当轮排序。

  • 首先从右边的高位指针right开始向左边遍历,直到找到比基准小的元素位置;然后从左边的低位开始向右遍历,直到找到比基准大的元素位置。

  • 如果指针未相遇,则交换左右指针指向的元素位置。如果指针已经相遇,即left==right,则将基准元素所在的位置与right所在位置的元素进行交换。

  • 重复上述过程,递归地对数组左右子集合元素进行排序。

2 用例说明

假设当前有一待排序的数组arr = 6,1,2,7,9,3,4,5,10,8。定义低位指针low = 0,高位指针high = arr,length - 1,选取首位为基准元素pivot = arrlow

  • 首先从右边的高位指针right开始向左边遍历,直到找到比基准小的元素位置,这里为元素5所在位置。

*6* ,1,2,7,9,3,4,**5**,10,8

  • 从左边的低位开始向右遍历,直到找到比基准大的元素位置,这里为元素7所在位置。

    *6* ,1,2,**7** ,9,3,4,**5**,10,8

  • 指针未相遇,则交换左右指针指向的元素7和元素5的位置。

    *6* ,1,2,**5** ,9,3,4,**7** ,10,8

    重读上述步骤,得到:*6* ,1,2,5,**9** ,3,**4** ,7,10,8,此时左右指针未相遇,继续交换位置。

    *6* ,1,2,5,**4** ,3,**9** ,7,10,8

    当第三次遍历时,做哦鱼指针在元素为3的位置上相遇,此时结束循环遍历,交换基准元素与元素3的位置,第一轮排序结束得到以下数组
    3,1,2,5,4,**6** ,9,7,10,8 可以看到一轮排序之后基准元素左半边的元素值都小于它,右半边的元素值都大于它。
    通过递归重复上述步骤,分别对数组左子集合3,1,2,5,4和数组右子集合9,7,10,8进行排序。

3 代码实现

java 复制代码
public static void quickSort(int[] arr, int low, int high) {
        // 当low == high时表示该序列只有一个元素了,不必排序
         if(low >= high) {
             return;
         }
         int left = low;  //定义左哨兵
         int right = high;   //定义右哨兵
         int pivot = arr[low];   //定义基准元素,一般选择数组的第一个元素
         while (left < right) {
             //从右边开始遍历 找到右边小于基准元素pivot的元素位置
             while (left < right && arr[right] >= pivot) {
                 right--;
             }
             //从左边开始遍历 找到左边大于基准元素pivot的元素位置
             while (left < right && arr[left] <= pivot) {
                 left++;
             }
             //找到了当前左边大于pivot和右边小于pivot的元素位置 交换这两个元素的位置
            swap(arr,left,right);
         }
         //当left == right 说明该轮排序结束,最后交换pivot与right位置元素的位置
        swap(arr, low, right);

         //递归调用,对左子集合和右子集合进行排序
        //左子集合递归排序
        quickSort(arr,low, right - 1);
        //右子集合递归排序
        quickSort(arr, right + 1, high);

    }

    //交换数组中两个位置的元素
    public static void swap(int[] arr, int i, int j) {
        if (arr.length == 0 || j >= arr.length || i < 0) return;
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
相关推荐
怪兽学LLM1 分钟前
LeetCode 438 找到字符串中所有字母异位词(Python 固定滑动窗口+字符计数解法)
python·算法·leetcode
满怀冰雪6 分钟前
第04篇-双指针算法-从有序数组到回文判断的高频解法
java·算法
CC数学建模7 分钟前
2026年江西省研究生数学建模竞赛1题:空间数据分析中的过拟合识别完整思路、代码、模型、文章,全网首发高质量分享!
python·算法·数学建模
matlabgoodboy7 分钟前
计算机java程序代写python代码编写c/c++代做qt设计php开发matlab
java·c语言·python
leo__52014 分钟前
MATLAB实现牧羊人算法
开发语言·算法·matlab
视觉小萌新18 分钟前
C++利用libmicrohttpd制作交互网页端——C1
java·c++·交互
Gauss松鼠会20 分钟前
【GaussDB】GaussDB SMP特性调优详解
java·服务器·前端·数据库·sql·算法·gaussdb
Tisfy25 分钟前
LeetCode 3689.最大子数组总值 I:What The Medium
算法·leetcode·题解·贪心·模拟·脑筋急转弯
葬送的代码人生25 分钟前
JavaScript 数组完全指南:从入门到实战
前端·javascript·算法
格发许可优化管理系统27 分钟前
Mentor许可证使用规定全解析
java·大数据·c语言·开发语言·c++