快速排序算法,简洁,易懂

本文详细介绍了快速排序算法的实现过程,包括使用首元素和中间元素作为基准值的方法,以及递归和分治策略的应用。通过Java代码示例,展示了如何手动和以中间元素划分进行排序。
摘要由CSDN通过智能技术生成

目录

代码实现(java): 

一、首元素作为基准值

图:

​编辑

基本思路:

代码:

代码补充说明:

二、中间元素作为基准值

代码:

 参考学习文章:


今天我们不刷力扣了,我们来复习(手撕)一下数据结构中的八大排序算法之一,快速排序

基本概念:

快速排序使用分治法策略来把一个串行分为两个子串行。

快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法 

注 : 分治法:Divide and conquer,行: list,子串行: sub-lists

冒泡排序冒泡排序,详详解解-CSDN博客 

上图:

算法步骤:

1、首先在数组中挑选一个元素作为基准值

2、将数组中大于基准值的元素,移到基准值右边

3、将数组中小于基准值的元素,移到基准值左边

4、对基准值左右 两侧的子序列重复上述操作(以递归方式)

注 :

1、基准值:pivot     递归:recursive 

2、基准值选择,第一个元素或者中间元素

代码实现(java): 

        main函数

public class QuickSort {
  
    public static void main(String[] args) {
        int[] arr = {3, 45, 78, 99, 45, 11, 64, 55, 52, 11, 18, 66, 17, 37, 199, 120, 54, 49};
        System.out.println("未排序的数组:" + Arrays.toString(arr));
        
        quickSort01(arr, 0, arr.length - 1);
        
         System.out.println("排序的数组:" + Arrays.toString(arr));
    }

注意:  传过去的参数 是数组首和尾元素 

一、首元素作为基准值

图:
基本思路:

首先将left与right指针 赋值给   临时指针le和ri

while循环( le和ri指针相遇时跳出循环)

      ·循环右指针ri左移,遇到小于或等于基准值元素  停止移动

      ·循环右指针le右移,遇到大于或等于基准值元素  停止移动 

      · if 判断

               若le与ri相遇即指向同一元素,则将该元素与与数组第一个元素互换

              否则将le与ri所指向元素互换位置

最后递归对对基准值左右两边数进行排序

代码:
 /**
     *  快速排序算法(以第一个元素为基准)
     *  @param arr 排序的数组
     * @param left 数组的第一个元素索引
     * @param right 数组的最后一个元素索引
     */
 
    private static void quickSort01(int[] arr,int left,int right){
        if (left >= right)  return;//递归退出条件

        int le = left;//le为数组的左指针
        int ri = right;//ri为数组的右指针
        
        while (le<ri){
                       //若右指针所指元素 大于或等于 基准数,右指针左移
           while (arr[ri]>=arr[left] && le<ri)    ri--;
    
                      //若左指针所指元素 小于或等于 基准数,左指针右移
           while (arr[le]<=arr[left] && le<ri )  le++;
           
            if (le == ri){/若两个指针指向同一元素,将此元素 与第一个元素 对调位置
                int tmp = arr[left];
                arr[left] = arr[ri];
                arr[ri] = tmp;

            }else{//若两个指针没有指向同一个位置,将两个指针 所指向的元素 对调位置
                int tmp = arr[le];
                arr[le] = arr[ri];
                arr[ri] = tmp;
            }
        }
        quickSort02(arr,left,le-1);//递归方式对基数左边的数进行排序
        quickSort02(arr,ri+1,right);//递归方式对基数右边的数进行排序
    }
}
代码补充说明:

 1、当le与ri指针相遇时,基准值被移动到中间了,或说 le与ri指针指向中间

         此时,left --- le-1为基准值 左边子序列 ,同理 ri+1 --- right为基准值 右边子序列

2、三个循环都有条件,当le和ri指针相遇时跳出循环

二、中间元素作为基准值

代码:
    /**
     * 快速排序算法(以中间元素为基准)
     * @param arr     排序的数组
     * @param left    左指针
     * @param right   右指针
     */
    private static void quickSort01(int[] arr,int left,int right){
       
       int l = left;
       int r = right;
      
       int pi = arr[(left+right)/2];//选取数组中间元素作为基准
       int tmp = 0;//tmp作为中间转换变量
       
       while (l<r) {
           while (arr[l] < pivot) {//当左元素小于基准时,就往右进一位
               l++;
           }
           
           while (arr[r] > pivot) {//当右元素大于基准时,就往左进一位
               r--;
           }
          
           if (l >= r) {//当两个指针指向同一个位置时,就跳出循环
               break;
           }
         
          //交换值,左指针所指大于基准值的与右指针所指小于基准值的交换位置
           temp = arr[l];
           arr[l] = arr[r];
           arr[r] = temp;
 
           if (arr[l] == pivot) {//如果左指针指向元素的值等于基准值,右指针往左移动一格
               r--;
           }
           if (arr[r] == pivot) {//如果右指针指向元素的值等于基准值,左指针往右移动一格
               l++;
           }
       }
      
        //第一次排序结束后,用递归的方式,
        //开始对基准值两边的元素开始排序
       if (l==r){
           l++;
           r--;
       }
       if (left<r){
           quickSort01(arr,left,r);
       }
       if (l<right){
           quickSort01(arr,l,right);
       }
    }

结果:

 

 参考学习文章:

1.6 快速排序 | 菜鸟教程 (runoob.com)

排序——快速排序(Quick sort)-CSDN博客

快速排序算法_快速排序所选pivot序列-CSDN博客

重温经典排序算法之快速排序——图解+C/C++实现_c++快速排序算法解析-CSDN博客

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值