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

目录

代码实现(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博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/463866.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java Web项目—餐饮管理系统Day07-套餐管理(二)

文章目录 1. 套餐的分页查询2. 更新套餐![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/209298cf3b4349c5a2fed56a3d33350e.png)第一步, 依据套餐id查询到套餐的基本信息以及关联菜品信息.第2步, 将请求数据进行保存(更新). 3. 批量的停售启售 这部分开发剩下的部分…

CSS Module

CSS Module的作用&#xff1a;将CSS样式作用域限制在特定的组件范围内&#xff0c;以避免全局样式污染和命名冲突。 Vue中如何实现样式模块…

SVN修改已提交版本的注释

目录 一、需求分析 二、问题分析 三、解决办法 一、需求分析 ​开发过程中&#xff0c;在SVN提交文件后&#xff0c;发现注释写的不完整或不够明确&#xff0c;想再修改之前的注释文字​。 使用环境&#xff1a; SVN服务器操作系统&#xff1a;Ubuntu 20.04.6 LTS SVN版本&…

物理隔离条件下,如何安全高效地进行内外网文件导入导出?

内外网文件导入导出通常指的是在内部网络&#xff08;内网&#xff09;和外部网络&#xff08;外网&#xff09;之间传输文件的过程。这在企业环境中尤其常见&#xff0c;因为内部网络通常包含敏感数据&#xff0c;而外部网络&#xff08;如互联网&#xff09;则允许更广泛的访…

计算机网络实验——学习记录

1. tun/tap模块&#xff1a;为Linux系统提供网络虚拟功能&#xff0c;tun位于网络OSI模型的三层&#xff08;网络层&#xff09;&#xff0c;tap位于网络的二层&#xff08;数据链路层&#xff09;。 1.1 验证是否包含tun/tap模块&#xff1a;modinfo tun&#xff1b; 1.2 验…

8:00面试,8:06就出来了,问的问题有点变态。。。

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到9月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40%…

echarts散点图自定义tooltip,鼠标放上去展示多行数据

先放效果图 如图&#xff0c;就是鼠标悬停在散点上&#xff08;这里的散点我替换成了图片&#xff0c;具体做法参考这篇文章&#xff1a;echarts散点图的散点用自定义图片替代-CSDN博客&#xff09;时&#xff0c;可以展示多行数据。之前查找资料的时候&#xff0c;很多用字符串…

封装哈希表

本文旨在讲解哈希表的封装&#xff0c;我们以哈希桶的结构来进行封装unorderedmap/set。要想实现封装哈希表&#xff0c;我们首先得先将哈希表的结构给搭建出来&#xff0c;然后再根据哈希桶的结构进一步封装unorderedmap/set&#xff01; 下面我们先来实现哈希桶的结构&#x…

12_Linux内核结构

Linux内核结构 1.内核的主要组成部分 Linux 内核主要的 5 个部分&#xff1a;进程调度、内存管理、虚拟文件系统、网络接口、进程通信。在系统移植的时候&#xff0c;它们是内核的基本元素&#xff0c;这 5 个部分之间的关系&#xff0c;如图所示&#xff1a; 进程调度&#…

V-JEPA模型,非LLM另外的选择,AGI的未来:迈向Yann LeCun先进机器智能(AMI)愿景的下一步

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

小怂爱水洼DFS

分析&#xff1a; 非常明显的搜索问题&#xff0c;当时我在写的时候遇到了两个问题&#xff0c;就一直没过。 1.忘记判断临界条件&#xff0c;x&#xff0c;t不能越界的问题&#xff1b; 2.最后有两个案例一直不能过&#xff0c;就是因为我用的int型的接受结果范围太小了&#…

前端学习从0到1第一天:初见html

阅读须知&#xff1a; 探索者安全团队技术文章仅供参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作,由于传播、利用本公众号所提供的技术和信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者 本人负责&#xff0c;作者不为此承担任何责任,如…

【C++中日期类的实现】

一路&#xff0c;一路&#xff0c;一路从泥泞到风景............................................................................................... 目录 前言 一、【什么是日期类】 二、【代码实现】 1.【Date.h】部分&#xff1a; 2.【Date.cpp】部分&#xff1a;…

关于ffmpeg height not divisible by 2的错误

在我们线上视频生产过程中&#xff0c;我们用ffmpeg对视频做了resize&#xff0c;讲原有的分辨率resize到1280p&#xff0c;使用了参数 -vf "scale1280:-1"&#xff0c;作用是将原始视频宽度缩放成1280&#xff0c;-1是指高度等比例缩放。 之前一直运行的好好的&…

储能技术发展

一、政策背景 “十三五”是我国储能产业化发展的起点。自“十四五”之后&#xff0c;各类储能支持政策更是以极快的速度不断更新完善。 2023年1月17日&#xff0c;工业和信息化部等六部门发布了《关于推动能源电子产业发展的指导意见》&#xff0c;其中明确提出要在2025年实现…

吴恩达prompt 笔记2:迭代提示开发(Iterative Prompt Develelopment)

1 前言 我们很难在初次尝试中就设计出最佳的提示&#xff0c;因此需要根据ChatGPT的反馈进行分析&#xff0c;分析输出具体在哪里不符合期望&#xff0c;然后不断思考和优化提示。如果有条件的话&#xff0c;最好是利用批量的样本来改善提示&#xff0c;这样可以对你的优化结…

代码随想录阅读笔记-哈希表【三数之和】

题目 给你一个包含 n 个整数的数组 nums&#xff0c;判断 nums 中是否存在三个元素 a&#xff0c;b&#xff0c;c &#xff0c;使得 a b c 0 &#xff1f;请你找出所有满足条件且不重复的三元组。 注意&#xff1a; 答案中不可以包含重复的三元组。 示例&#xff1a; 给定数…

Python之Web开发中级教程----搭建虚拟环境

Python之Web开发中级教程----搭建Web框架二 搭建虚拟环境 虚拟环境的作用 虚拟环境可以搭建独立的python运行环境, 使得单个项目的运行环境与其它项目互不影响. 搭建虚拟环境 &#xff08;1&#xff09;安装 sudo pip install virtualenv sudo pip install virtualenvwra…

一起学数据分析_2

写在前面&#xff1a;代码运行环境为jupyter&#xff0c;如果结果显示不出来的地方就加一个print()函数。 一、数据基本处理 缺失值处理&#xff1a; import numpy as np import pandas as pd#加载数据train.csv df pd.read_csv(train_chinese.csv) df.head()# 查看数据基本…

Vue3-响应式基础:单文件和组合式文件

单文件&#xff1a;html <!DOCTYPE html> <html> <head><title>响应式基础</title> </head> <body><div id"app" ><!-- dynamic parameter:同样在指令参数上也可以使用一个 JavaScript 表达式&#xff0c;需要包…