算法通关村第十关—快速排序(青铜)

快速排序

快排的基本过程

快速排序是将分治法运用到排序问题的典型例子

快速排序基本思想是:通过一个标记pivot元素将n个元素的序列划分为左右两个子序列left和right,.其中left中的元素都比pivot小,right的都比pivot的大,然后再次对Ieft和right各自再执行快速排序,在将左右子序列排好序之后,整个序列就有序了。这里排序进行左右划分的时候是一直划分到子序列只包含一个元素的情况,然后再递归返回。

我们以关键字序列{26,53,48,15,13,48,32,15}看一下一次划分的过程:

上面红框位置表示当前已经被赋值给了pot或者其他位置,可以空出来放移动来的新元素了。我们可以看到26最终被放到了属于自己的位置上,不会再变化。而左侧的都比26小,左侧都比26大,因此26的左右两侧可以分别再进行排序。

代码实现

前面部分是利用快慢指针,慢指针可以确定枢轴,然后对枢轴两侧的序列通关递归继续快排

java 复制代码
public static void quickSort(int[] arr,int left, int right){
    if (left < right){
        int pivot = arr[right];
        int i = left - 1;
        for(int j = left; j < right; j++){
            if (arr[j] < pivot){
                i++;
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
            //哨兵移动到位置pivotIndex上
            int pivotIndex = i + 1;
            int temp = arr[pivotIndex];
            arr[pivotIndex] = arr[right];
            arr[right] = temp;

            quickSort(arr, left, pivotIndex - 1);
            quickSort(arr, pivotIndex + 1, right);
        }
    }

快排有很多种实现方式,这是第二种:"二叉树的前序遍历+对撞型双指针"

java 复制代码
void quickSort(int[] array,int start, int end){
    if (start >= end){
        return;
    }
    //这里就是一个对撞的双指针操作
    int left = start, right = end;
    int pivot = array[(start + end) / 2];
    while(left < right){
        while(left < right && array[left] < pivot)
        left++;
        while(left < right && array[right] > pivot)
        right--;

        if(left < right){
            int temp = array[left];
            array[left] = array[right];
            array[right] = temp;
            left++;
            right--;
        }
    }
    //先处理元素再分别递归处理两侧分支,与二叉树的前序遍历非常像
    quickSort(array,start,right);
    quickSort(array,left,end);
}

复杂度分析

快速排序的时间复杂度计算比较麻烦一些。从原理来看,如果我们选择的pivot每次都正好在中间,效率是最高的,但是这是无法保证的,因此我们需要从最好、最坏和中间情况来分析

1.最坏情况就是如果每次选择的恰好都是Iow结点作为pivot,如果元素恰好都是逆序的,此时时间复杂度为O(n^2)

2.如果元素恰好都是有序的,则时间复杂度为O(n)

3.折中的情况是每次选择的都是中间结点,此时序列每次都是长度相等的序列,此时的时间复杂度为(O(nlogn))

相关推荐
softbangong3 分钟前
816-批量将图片分别转为pdf,文件夹下所有图片转为一个pdf
java·服务器·pdf·图片处理·图片转pdf·pdf工具·批量转换
玛卡巴卡ldf3 分钟前
【LeetCode 手撕算法】(矩阵)73-矩阵置零、54-螺旋矩阵(贪吃蛇)、48-旋转图像
java·数据结构·算法·leetcode·力扣
C^h3 分钟前
RTthread中的内存池理解
linux·数据库·c++·算法·嵌入式
深藏功yu名3 分钟前
Day25(高阶篇):RAG检索与重排序算法精研|从原理到参数调优,彻底攻克检索瓶颈
人工智能·算法·ai·自然语言处理·排序算法·agent
程序员小寒5 分钟前
JavaScript设计模式(四):发布-订阅模式实现与应用
开发语言·前端·javascript·设计模式
不吃香菜学java5 分钟前
苍穹外卖-新增套餐
java·spring boot·spring·tomcat·maven·mybatis
csbysj20205 分钟前
JSON 语法
开发语言
wangchunting6 分钟前
Spring Boot 概述
java·spring boot·后端
郝学胜-神的一滴8 分钟前
深入解析:生成器在UserList中的应用与Python可迭代对象实现原理
开发语言·python·程序人生·算法
雪木木8 分钟前
刷题:力扣热题100--滑动窗口(Day03)
算法·leetcode